简述
ReentrantLock是juc包下的一个类,它是一个可重入且独占式的锁,它具有与使用synchronized监视器锁相同的基本行为和语义,但与synchronized关键字相比,它更灵活、更强大,增加了轮询、超时、中断等高级功能。
ReenreantLock可以中断——a线程用着锁,b线程能中断,设置超时时间——在entrylist等待锁的线程在规定时间内获取不到锁就会放弃锁的获取,可以设置为公平锁——让线程都排队等先到先得,支持多个条件变量——可以理解为有多个waitset。
基本语法
reentrantLock的锁需要新建一个对象来使用
// 获取锁 reentrantLock.lock(); try { // 临界区 } finally { // 释放锁 reentrantLock.unlock(); }
可重入
reentrantLock和synchronized一样,也是可重入的锁。可重入是指同一个线程如果首次获得了这把锁,那么因为它是这把锁的拥有者,因此有权利再次获取这把锁。如果是不可重入锁,那么第二次获得锁时,自己也会被锁挡住。
可打断
使用reentrantLock可以在等锁的时候被打断,想以可以被打断的方式获取断锁用lockInterruptibly方法。其他线程可以使用该线程的interrupt方法打断该线程
锁超时
tryLock方法代表尝试获取锁,返回boolean值,代表是否成功获取了锁。
它还可以加一个时间参数,获取不到锁时,等待该时间,时间到则返回false
同时需要注意的是这种方式获取锁也是可以被打断的
公平锁
reentrantLock默认是不公平的,可以在构造方法传一个true设置reentrantLock锁为公平锁
公平锁是用来解决饥饿问题的,线程在尝试获取锁的时候是先到先得的机制
条件变量
reentrantLock有多个waitset,线程等待时可以选择一个进行等待,唤醒等待线程时可以选择一个waitset唤醒。
可以用newCondition创建条件变量类,等同于创建一个waitset
可以调用Condition类的await进入等待队列,使用signal方法唤醒该Condition上等待的线程
需要注意await 前需要获得锁,await 执行后,会释放锁,进入 conditionObject 等待,await 的线程被唤醒(或打断、或超时)取重新竞争 lock 锁,竞争 lock 锁成功后,从 await 后继续执行