一文详解 Java 的几把 JVM 级锁( 四 )
ReentrantLock
ReentrantLock 从字面可以看出是一把可重入锁 , 这点和 synchronized 一样 , 但实现原理也与 syncronized 有很大差别 , 它是基于经典的 AQS(AbstractQueueSyncronized) 实现的 AQS 是基于 volitale 和 CAS 实现的 , 其中 AQS 中维护一个 valitale 类型的变量 state 来做一个可重入锁的重入次数 , 加锁和释放锁也是围绕这个变量来进行的 。 ReentrantLock 也提供了一些 synchronized 没有的特点 , 因此比 synchronized 好用 。 AQS模型如下图: ReentrantLock 有如下特点: 1、可重入 ReentrantLock 和 syncronized 关键字一样 , 都是可重入锁 , 不过两者实现原理稍有差别 , RetrantLock 利用 AQS 的的 state 状态来判断资源是否已锁 , 同一线程重入加锁 , state 的状态 +1 ; 同一线程重入解锁 state 状态 -1 (解锁必须为当前独占线程 , 否则异常); 当 state 为 0 时解锁成功 。 2、需要手动加锁、解锁 synchronized 关键字是自动进行加锁、解锁的 , 而 ReentrantLock 需要 lock() 和 unlock() 方法配合 try/finally 语句块来完成 , 来手动加锁、解锁 。 3、支持设置锁的超时时间 synchronized 关键字无法设置锁的超时时间 , 如果一个获得锁的线程内部发生死锁 , 那么其他线程就会一直进入阻塞状态 , 而 ReentrantLock 提供 tryLock 方法 , 允许设置线程获取锁的超时时间 , 如果超时 , 则跳过 , 不进行任何操作 , 避免死锁的发生 。 4、支持公平/非公平锁 synchronized 关键字是一种非公平锁 , 先抢到锁的线程先执行 。 而 ReentrantLock 的构造方法中允许设置 true/false 来实现公平、非公平锁 , 如果设置为 true , 则线程获取锁要遵循\"先来后到\"的规则 , 每次都会构造一个线程 Node , 然后到双向链表的\"尾巴\"后面排队 , 等待前面的 Node 释放锁资源 。 5、可中断锁 ReentrantLock 中的 lockInterruptibly() 方法使得线程可以在被阻塞时响应中断 , 比如一个线程 t1 通过 lockInterruptibly() 方法获取到一个可重入锁 , 并执行一个长时间的任务 , 另一个线程通过 interrupt() 方法就可以立刻打断 t1 线程的执行 , 来获取t1持有的那个可重入锁 。 而通过 ReentrantLock 的 lock() 方法或者 Synchronized 持有锁的线程是不会响应其他线程的 interrupt() 方法的 , 直到该方法主动释放锁之后才会响应 interrupt() 方法 。
推荐阅读
- 原神|原神:阿贝多有什么用?兼顾副C与辅助,三大作用机制详解
- |《哈利波特: 魔法觉醒》学院活动保护南瓜攻略详解教程
- 碧蓝航线|碧蓝航线SR重巡福煦数据详解 期待越高失望越大 强度平平无奇
- fate grand order|fgo五星降临者梵高强度详解 暴击队最强天拐核心 从此刀刀烈火
- steam|阴阳师铁鼠新皮肤详解 对弈竞猜破产风格 玩家遭遇天台局的现状
- 伊利丹·怒风|魔兽TBC:伊利丹招牌技能,“剪切”机制详解,盾坦闭眼都能抗?
- 假面骑士|假面骑士live腰带官方详解 蝙蝠拔刀和拔枪 加油枪和手持吸尘器
- 神之手|黑暗特利迦裂口双形态能力详解 暴热神之手与闪电高速涡轮冲击
- 射击|魔兽TBC:猎人输出手法,“5511机制”详解,与抽筋宏有何区别?
- 三国志|三国志战略版6套T0天花板共存配置,阵容克制和被克制详解!