reentrantlock 原理
reentrantlock 原理
程序员朱永胜有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准
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()
: 获取锁,但优先响应中断。
代码示例
1 | import java.util.concurrent.locks.ReentrantLock; |
在上面的代码示例中,我们创建了一个 ReentrantLock
实例,并在 performAction
方法中使用它来保护临界区代码。通过在 try
块中编写业务逻辑,并在 finally
块中释放锁,我们确保了即使在发生异常的情况下,锁也会被释放。
总结来说,ReentrantLock
是一个强大的同步工具,它提供了比 synchronized 更细粒度的锁控制,包括尝试获取锁、定时锁等待和中断等待锁的能力,同时还支持公平性选择。