ReentrantLock-互斥同步器

小编 2026-06-05 阅读:1990 评论:0
‍ReentrantLo...

‍ReentrantLock是一个互斥的同步器,其实现了接口Lock,里面的功能函数主要有:
1. ‍lock() -- 阻塞模式获取资源
2. ‍lockInterruptibly() -- 可中断模式获取资源
3. ‍tryLock() -- 尝试获取资源
4. tryLock(time) -- 在一段时间内尝试获取资源
5. ‍unlock() -- 释放资源

ReentrantLock实现Lock有两种模式即公平模式和不公平模式
Concurrent包下的同步器都是基于AQS框架,在ReentrantLock里面会看到这样三个类
-----------------------------------------------------------------------
static abstract class Sync extends AbstractQueuedSynchronizer {
    abstract void lock();
    final boolean nonfairTryAcquire(int acquires) { ... }
    protected final boolean tryRelease(int releases) { ... }
}
-----------------------------------------------------------------------
final static class NonfairSync extends Sync {
    protected final boolean tryAcquire(int acquires) { ... }
    final void lock() { ... }
}
-----------------------------------------------------------------------
final static class FairSync extends Sync {
    final void lock() { ... }
    protected final boolean tryAcquire(int acquires) { ... }
}
-----------------------------------------------------------------------
再回归到ReentrantLock对Lock的实现上
0. ‍ReentrantLock实例化
   ReentrantLock有个属性sync,实际上对Lock接口的实现都是包装了一下这个sync的实现
   如果是公平模式则创建一个FairSync对象,否则创建一个NonfairSync对象,默认是不公平模式
1. lock() 调用sync.lock()
   公平模式下:直接走AQS的acquire函数,此函数的逻辑走一次tryAcquire,如果成功
   线程拜托同步器的控制,否则加入NODE链表,进入acquireQueued的tryAcquire,休眠,被唤醒的轮回
   不公平模式下和公平模式下逻辑大体上是一样的,不同点有两个:
   a. 在执行tryAcquire之前的操作,不公平模式会直接compareAndSetState(0, 1)原子性的设置AQS的资源
   0表示目前没有线程占据资源,则直接抢占资源,不管AQS的NODE链表的FIFO原则
   b. tryAcquire的原理不一样,不公平模式的tryAcquire只看compareAndSetState(0, 1)能否成功
   而公平模式还会加一个条件就是此线程对于的NODE是不是NODE链表的第一个
   c. 由于tryAcquire的实现不一样,而公平模式和不公平模式在lock期间走的逻辑是一样的(AQS的acquireQueued的逻辑)
   d. 对于一个线程在获取到资源后再调用lock会导致AQS的资源做累加操作,同理线程要彻底的释放资源就必须同样
   次数的调用unlock来做对应的累减操作,因为对应ReentrantLock来说tryAcquire成功一个必须的条件就是compareAndSetState(0, 1)
   e. 由于acquireQueued过程中屏蔽了线程中断,只是在线程拜托同步器控制后,如果记录线程在此期间被中断过则标记线程的
   中断状态
2. ‍lockInterruptibly() 调用sync.acquireInterruptibly(1),上一篇文章讲过AQS的核心函数,这个过程和acquireQueued
   是一样的,只不过在阻塞期间如果被标记中断则线程在park期间被唤醒,然后直接退出那个轮回,抛出中断异常
   由于公平模式和不公平模式下对tryAcquire的实现不一样导致‍lockInterruptibly逻辑也是不一样
3. tryLock() 函数只是尝试性的去获取一下锁,跟tryAcquire一样,这两种模式下走的代码一样都是公平模式下的代码
4. tryLock(time) 调用sync.tryAcquireNanos(time),上一篇文章讲过AQS的核心函数,这个过程和acquireQueued一样,
   a. 在阻塞前会先计算阻塞的时间,进入休眠
   b. 如果被中断则会判断时间是否到了
      1. 如果没到则且被其他线程设置了中断标志,退出那个轮回,抛出中断异常,如果没有被设置中断标记则是前一个线程
      释放了资源再唤醒了它,其继续走那个轮回,轮回中,如果tryAcquire成功则摆脱了同步器的控制,否则回到a
      2. 如果时间到了则退出轮回,获取资源失败
5. ‍unlock() 调用sync.release(1),上一篇文章讲过AQS的核心函数,release函数会调用Sync实现的tryRelease函数来判断
   释放资源是否成功,即Sync.tryRelease函数,其逻辑过程是
   a. 首先判断目前占据资源的线程是不是调用者,如果不是会抛出异常IllegalMonitorStateException
   b. 如果是则进行AQS资源的减1逻辑,如果再减1后AQS资源变成0则表示调用线程测得放弃了此锁,返回给release的值的TRUE,
   release会唤醒下一个线程
-----------------------------------------------------------------------
整体来看ReentrantLock互斥锁的实现大致是
1. 自己实现AQS的tryAcquire和tryRelease逻辑,tryAcquire表示尝试去获取锁,tryRelease表示尝试去释放锁
2. ReentrantLock对lock(),trylock(),trylock(time),unlock()的实现都是使用AQS的框架,然后AQS的框架又返回调用
ReentrantLock实现的tryAcquire和tryRelease来对线程是否获取锁和释放锁成功做出依据判断

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表