ReentrantLock是Java线程同步的一种方式,在Java多线程编程经常用到,下面重点来详解ReentrantLock@mikechen
ReentrantLock定义
ReentrantLock是Java中的一个可重入锁,是一种比synchronized更加灵活和强大的同步机制。
ReentrantLock组成
通过上图的继承关系,我们都能大概梳理出ReentrantLock的处理逻辑。
内部定义了三个重要的静态内部类:Sync,NonFairSync,FairSync
- Sync作为ReentrantLock中公用的同步组件,继承了AQS(要利用AQS来实现线程排队,阻塞,唤醒等等)
- NonfairSync(非公平锁) 继承 Sync 抽象类
- FairSync(公平锁) 继承 Sync 抽象类
ReentrantLock原理
在具体实现上,ReentrantLock是基于AQS来实现,AQS全名:AbstractQueuedSynchronizer,AQS是一个用于实现同步器的类。
除了ReentrantLock基于AQS,还有Semaphore、CountDownLatch等的底层实现方式也是基于AQS来实现。
AQS它实现了一个FIFO的队列,底层实现的数据结构是一个双向链表,如下图所示:
AQS维护了一个状态变量state,用于表示锁的状态,以及一个线程变量exclusiveOwnerThread,用于记录当前持有锁的线程。
具体实现,大致分为如下几点:
- ReentrantLock在调用lock()方法时,会首先判断当前线程是否已经持有锁;
- 如果是,则将锁的重入次数加1,并返回;
- 否则,将当前线程加入到等待队列中,等待获取锁。
ReentrantLock使用
下面是一个简单的使用ReentrantLock的示例:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ReentrantLockDemo { private Lock lock = new ReentrantLock(); // 创建一个ReentrantLock对象 public void print() { lock.lock(); // 获取锁 try { System.out.println(Thread.currentThread().getName() + " is printing."); Thread.sleep(1000); // 模拟打印操作 } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); // 释放锁 } } public static void main(String[] args) { final ReentrantLockDemo demo = new ReentrantLockDemo(); // 创建多个线程并启动 for (int i = 0; i < 5; i++) { new Thread(() -> { demo.print(); }, "Thread-" + i).start(); } } }
我们创建了一个ReentrantLock对象,并在print()方法中使用了lock()和unlock()方法来获取和释放锁。
由于只有一个ReentrantLock对象,因此在同一时刻只有一个线程可以执行print()方法,其他线程需要等待该线程释放锁后才能获取锁并执行print()方法。
ReentrantLock应用
ReentrantLock适用于需要高度控制的并发环境,其应用场景包括但不限于以下5种:
- 需要实现公平或非公平的锁机制:ReentrantLock可以设置公平或非公平锁,以满足不同的需求。
- 需要限制等待锁的时间:ReentrantLock可以设置等待锁的时间,如果等待时间超过设定值,等待的线程就可以自动放弃锁的获取。
- 需要使用条件变量:ReentrantLock可以使用Condition对象来实现多个条件变量,可以更加精细地控制线程的等待和通知。
- 需要避免死锁:由于ReentrantLock支持可重入性,同一个线程可以多次获取同一把锁,这可以避免死锁的发生。
- 需要精确控制锁的释放:使用synchronized关键字时,锁的释放是由JVM自动控制的,而使用ReentrantLock可以手动控制锁的释放,以达到更精确的控制效果。
以上就是ReentrantLock的详解,更多Java线程锁,请查看:4种常用Java线程锁的特点,性能比较、使用场景
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》