一、ReentrantLock 概述
1.1 ReentrantLock 简介
故名思义,ReentrantLock 意为可重入锁,那么什么是可重入锁呢?可重入意为一个持有锁的线程可以对资源重复加锁而不会阻塞。比如下面这样:
public synchronized void f1() {
f2();
}
private synchronized void f2() {
}
ReentrantLock 除了支持可重入以外,还支持定义公平与非公平策略,默认情况下采用非公平策略。公平是指等待时间最长的线程会优先获取锁,也就是获取锁是顺序的,可以理解为先到先得。
公平锁保证了锁的获取按照 FIFO(先进先出)原则,但是需要大量的线程切换。非公平锁虽然减少了线程之间的切换增大了其吞吐量,但是可能会造成线程“饥饿”。
1.2 使用方式
public void f1() {
ReentrantLock lock = new ReentrantLock();
try {
lock.lock();
// ...
} finally {
lock.unlock();
}
}
与 synchronized 不同,使用 ReentrantLock 必须显示的加锁与释放锁。
1.3 与 synchronized 对比
相同点:
- 可重入,同一线程可以多次获得同一个锁
- 都保证了可见性和互斥性
不同点:
ReentrantLock可响应中断、可轮回,为处理锁的不可用性提供了更高的灵活性,synchronized不可以响应中断ReentrantLock是 API 级别的,synchronized是 JVM 级别(JVM 内置属性)的,因此内置锁可以与特定的栈帧关联起来ReentrantLock可以实现公平锁,切可以实现带有时间限制的操作ReentrantLock通过Condition可以绑定多个条件
二、源码分析
了解了 ReentrantLock 的基本概念后,接下来就一起来看源码吧。其实 ReentrantLock 内的源码并不多,原因在于很多源码都在 AbstractQueuedSynchronizer 中,因此想要了解 ReentrantLock 源码的小伙伴需要先行了解下 AQS。
后面会给大家推荐几篇关于 AQS 源码介绍的文章,有兴趣的可以自行了解,或者到我的 GitHub 去查下相应的源码记录。点我前往 GitHub
2.1 构造函数
默认构造函数
public ReentrantLock() {
sync = new NonfairSync();
}
有参构造函数
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync()

本文介绍了Java8中的ReentrantLock,详细分析了其可重入特性、公平与非公平策略,并对比了它与synchronized的区别。文章探讨了ReentrantLock的源码,包括构造函数、NonfairSync和FairSync的实现,以及如何通过AQS来管理同步状态。
最低0.47元/天 解锁文章
382

被折叠的 条评论
为什么被折叠?



