1、概述
ReentrantLock 翻译过来是可重入锁,相对于 synchronized 它具备以下特点:
- 可中断
- 可以设置超时时间
- 可以设置公平锁
- 支持多个条件变量 (类似于 wait 等待)
- 与 synchronized 一样,都支持重入
注意:一定要去释放锁,要不然就会死锁
2、原理
ReentrantLock 主要利用 CAS+AQS 队列来实现。它支持公平锁和非公平锁,两者的实现类似
构造方法接受一个可选的公平参数(默认非公平锁),当设置为 true 时,表示公平锁,否则为非公平锁。公平锁的效率往往没有非公平锁的效率高,在许多线程访问的情况下,公平锁表现出较低的吞吐量。
查看 ReentrantLock 源码中的构造方法:
[!note]
无参方法:创建一个公平锁
false:非公平锁
3、工作流程
工作流程
- 线程来抢锁后使用cas的方式修改state状态,修改状态成功为1,则让exclusiveOwnerThread属性指向当前线程,获取锁成功
- 假如修改状态失败,则会进入双向队列中等待,head指向双向队列头部,tail指向双向队列尾部
- 当exclusiveOwnerThread为null的时候,则会唤醒在双向队列中等待的线程
- 公平锁则体现在按照先后顺序获取锁,非公平体现在不在排队的线程也可以抢锁
总结:
- ReentrantLock 是一个可重入锁,调用 lock 方法获取了锁之后,再次调用 lock,是不会再阻塞,内部直接增加重入次数就行了,标识这个线程已经重复获取一把锁而不需要等待锁的释放。
- ReentrantLock 是属于 juc 报下的类,属于 api 层面的锁,跟 synchronized 一样,都是悲观锁。通过 lock ()用来获取锁,unlock ()释放锁。
- 它的底层实现原理主要利用CAS+AQS 队列来实现。它支持公平锁和非公平锁,两者的实现类似
- 构造方法接受一个可选的公平参数(默认非公平锁),当设置为true时,表示公平锁,否则为非公平锁。公平锁的效率往往没有非公平锁的效率高。