概述
顾名思义,ReentrantLock是重入锁。它实现了Lock接口,是基于AQS(一种用于构建同步器的框架)构造出来的一种同步器。
功能
同synchronized一样,ReentrantLock也是可重入的,与synchronized相比增加了一些高级功能,主要有以下三项:等待可中断、可实现公平锁、锁可以绑定多个条件
- 等待可中断:是指当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。可中断特性对处理执行时间非常长的同步块很有帮助。
- 公平锁:是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁。synchronized中的锁是非公平的,ReentrantLock在默认情况下也是非公平的,但是可以通过带布尔值的构造函数要求使用公平锁。不过一旦使用了公平锁,将会导致ReentrantLock的性能急剧下降,会明显影响吞吐量。
- 锁绑定多个条件:是指一个ReentrantLock对象同时可以绑定多个Condition对象。在synchronized中,锁对象的wait()跟他的notify()或者notifyAll()方法配合可以实现一个隐含的条件,如果要和多于一个条件关联的时候,就不得不额外添加一个锁;而ReentrantLock则无须这样做,多次调用newCondition()方法即可
虽然ReentrantLock有很多优点,但synchronized有它独特的优势:
- 使用简单,不易出错
- 经过JVM底层的锁优化之后,二者的性能相差不大。
- JVM可以再线程和对象的元数据中记录syn中锁的相关信息,而如果使用ReentrantLock,JVM很难得知具体那些锁对象是由特定线程所持有的。
整体结构
图中所示的FairSync即为ReentrantLock的公平锁实现,而NonfairSync为非公平锁实现。二者都继承了名为Sync的内部内,至于细节是如何实现的,这就涉及到了AQS模板类了。