ReentrantLock (独占锁、互斥锁)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReentrantLock (独占锁、互斥锁)相关的知识,希望对你有一定的参考价值。

参考技术A

我们知道锁的基本原理是,基于将多线程并行任务通过某一种机制实现线程的串 行执行,从而达到线程安全性的目的。而Lock是juc中实现的锁接口,他定义了锁的一些行为规范,他的设计目的是为了解决 synchronized 关键字在一些并发场景下不适用的问题。

juc 包下的接口,定义了锁的规范。有多种实现类。

ReentrantLock 重入锁 一个持有锁的线程,在释放锁之前。此线程如果再次访问了该同步锁的其他的方法,这个线程不需要再次竞争锁,只需要记录重入次数。 重入锁的设计目的是为了解决死锁的问题

inr() 方法获取锁成功并没有释放锁的情况下调用dec()再次获取锁,假如没有重入锁的话这里会导致死锁。此线程如果再次访问了该同步锁的其他的方法,这个线程不需要再次竞争锁,只需要记录重入次数。

<span style=\'color:red\'>内部是如何实现的?假如线程中断锁没有及时释放怎么办呢</span>

NonfairSync 重入锁的核心实现

AQS中维护了一个存储了等待线程的Node节点的双端链表,有首节点head与尾节点tail,创建一个Node节点里面存储的是当前线程,如果已经有了tail节点则尝试cas操作添加当前节点到链表的尾结点,如果没有则进行初始化操作cas操作创建一个head节点并且自旋(没有任何结束条件的循环)cas操作添加尾结点到链表的尾部,最终返回新增的Node节点。

对于插入到等待队列中的Node节点通过 addWaiter 方法把线程添加到链表后,会接着把 Node 作为参数传递给 acquireQueued 方法,去再次竞争锁

挂起当前线程。这里调用了LockSupport.park(this)把线程挂起了并返回 Thread.interrupted() 线程复位。

释放锁的业务逻辑不需要考虑多线程的问题,他还是被一个线程持有。因为重入锁的机制state>=1 释放就是 getState() - releases并跟新state为最新值,如果state=0则返回。

以上是关于ReentrantLock (独占锁、互斥锁)的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock

多线程编程-- part5.1 互斥锁ReentrantLock

JUC——线程同步锁(ReentrantLock)

Java锁--ReentrantLock

AQS-ReentrantLock

并发编程—独占锁和共享锁