有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准
https://blog.zysicyj.top
全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。 https://store.amazingmemo.com/chapterDetail/1685324709017001`
ReentrantLock 原理
ReentrantLock 是 Java 中的一个高级同步机制,它提供了比传统的 synchronized 方法和语句更丰富的操作。它属于 java.util.concurrent.locks 包下的一个类。ReentrantLock 允许一个线程多次获得同一把锁,即是可重入的。
基本原理
ReentrantLock 内部通过使用一个同步器(AbstractQueuedSynchronizer,简称 AQS)来实现锁的功能。AQS 使用一个整型的 volatile 变量(称为 state)来表示同步状态,以及一个 FIFO 队列来管理那些等待获取锁的线程。
状态(State)
- 当 state 为 0 时,表示锁没有被任何线程持有。
- 当 state 大于 0 时,表示锁被一个线程持有,并且 state 表示该线程获取锁的次数。
可重入性
ReentrantLock是可重入的,即如果当前线程已经持有锁,再次请求锁时会立即成功,并且 state 会相应地增加。- 当线程释放锁时,它会减少 state 的值。当 state 为 0 时,锁被完全释放。
锁的获取与释放
- 获取锁:当一个线程尝试获取锁时,如果 state 为 0,AQS 会将 state 设置为 1 并且设置当前线程为锁的持有者。如果当前线程已经持有锁(即尝试重入),AQS 会增加 state 的值。
- 释放锁:当线程释放锁时,它会调用
unlock()方法,AQS 会减少 state 的值。如果 state 为 0,则锁被完全释放,并且可能会唤醒在等待队列中等待这个锁的其他线程。
公平性和非公平性
ReentrantLock 提供了公平锁和非公平锁两种模式:
- 公平锁:在这种模式下,锁会按照线程在等待队列中的等待顺序来分配,即“先来先服务”。
- 非公平锁:在这种模式下,当锁可用时,任何请求它的线程都有机会获取锁,这可能会导致“线程饥饿”。
方法概览
ReentrantLock 提供了一些重要的方法:
lock(): 获取锁,如果锁不可用则等待。unlock(): 释放锁。tryLock(): 尝试获取锁,如果锁可用立即返回 true,否则返回 false。tryLock(long timeout, TimeUnit unit): 在给定的时间内尝试获取锁,如果在指定的时间内获取到锁则返回 true,否则返回 false。lockInterruptibly(): 获取锁,但优先响应中断。
代码示例
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private final ReentrantLock lock = new ReentrantLock();
public void performAction() {
lock.lock(); // 获取锁
try {
// 临界区代码
} finally {
lock.unlock(); // 释放锁
}
}
}
在上面的代码示例中,我们创建了一个 ReentrantLock 实例,并在 performAction 方法中使用它来保护临界区代码。通过在 try 块中编写业务逻辑,并在 finally 块中释放锁,我们确保了即使在发生异常的情况下,锁也会被释放。
总结来说,ReentrantLock 是一个强大的同步工具,它提供了比 synchronized 更细粒度的锁控制,包括尝试获取锁、定时锁等待和中断等待锁的能力,同时还支持公平性选择。
本文是原创文章,采用 CC BY-NC-SA 4.0 协议,完整转载请注明来自 小朱
评论
隐私政策
0/500
滚动到此处加载评论...


