ReentrantLock底层原理

ReentrantLock 是 Java 并发包 java.util.concurrent.locks 中的一个类,用于实现可重入的互斥锁。它的核心确实是基于 AbstractQueuedSynchronizer(简称 AQS)来实现

AQS 简介

AbstractQueuedSynchronizer 是一个为构建锁或其他同步组件而设计的框架。它使用了一个基于 FIFO(先进先出)的队列来管理等待获取资源的线程。AQS 使用了一个 int 类型的状态变量来表示同步状态,通过 CAS(Compare-And-Swap)操作来原子地更新这个状态。

AQS 有两种模式,一种是独占锁,表示只有一个线程能执行,另外一种是共享锁,表示可以多个线程同时执行。ReentrantLock是独占锁

ReentrantLock 与 AQS 的关系

ReentrantLock 并不是直接继承自 AbstractQueuedSynchronizer,而是内部定义了一个静态内部类 Sync,这个 Sync 类继承自 AbstractQueuedSynchronizer。ReentrantLock 通过这个内部类 Sync 来实现锁的功能

ReentrantLock工作原理

当线程尝试获取锁时,它会调用 ReentrantLock 的 lock() 方法,这最终会调用到 Sync 类的 acquire 方法。acquire 方法会调用 tryAcquire 方法来尝试获取锁。如果获取成功,线程就持有了锁(setExclusiveOwnerThread改成当前线程);如果获取失败,线程会被加入 AQS 的队列中等待。

当线程释放锁时,它会调用 ReentrantLock 的 unlock() 方法,这最终会调用到 Sync 类的 release 方法。release 方法会调用 tryRelease 方法来释放锁(setExclusiveOwnerThread改成null),并唤醒等待队列中的线程。

可重入原理

以非公平锁为例,他会先判断state状态,如果为0说明没有加锁,直接加锁
如果不为0说明上锁了就会判断当前线程是不是和exclusiveOwnerThread里面的一样,如果一样的话就说明是重入了,直接
释放的时候就会调用tryRelease方法,调用完就会state--,如果当减到0的时候,就会让锁释放掉,设置exclusiveOwnerThread为null,让state为0。

公平锁原理

非公平锁获取锁的时候如果为state为0说明没有人拿锁,他会直接去抢锁,没有任何判断。(简单说:谁抢到算谁的)
公平锁会多个判断条件,如果堵塞队列还有线程就不会去拿锁(简单说:按规则获取)

PS:若释放锁的时候,正好一个新线程A来抢锁,而此时位于队列头的线程还没有被唤醒(因为线程上下文切换是需要不少开销的),此时新线程A则优先获得锁,成为非公平锁;
其实对于非公平锁,只要线程进入了等待队列,队列里面依然是FIFO的原则,跟公平锁的顺序是一样的。因为公平锁与非公平锁的release()部分代码是共用AQS的代码。

可打断原理

分为可打断模式和不可打断模式,当调用doAcquireInterruptibly,也是去获取锁,然后park进入队列,这个时候别的线程唤醒它继续执行,直接是抛出InterruptedException异常就直接不用循环等待了,实现了可打断。

Condition

相比较synchronize的wait()和notify()/notifAll()的机制而言,Condition具有更高的灵活性,这个很关键。Condition实现线程等待和唤醒

使用场景:线程A执行到某个点的时候,因为某个条件condition不满足,需要线程A暂停;等到线程B修改了条件condition,使condition满足了线程A的要求时,A再继续执行

总结

  •     ReentrantLock是可重入的互斥锁,它的核心基于AQS。AQS使用基于FIFO(先进先出)的队列来管理等待的线程
  •    ReentrantLock中加锁和释放锁并不是直接使用AQS,而是使用它内部定义的一个sync类(两个子类FairSync/UnFairSync实现公平锁和非公平锁)来实现的。
  •     在获取锁时,使用Sync类中的acquire方法来获取锁,获取成功的话,线程持有该锁,获取失败的话,线程会被加入AQS队列中等待。在释放锁时, 使用Sync类的release方法来释放锁,同时唤醒等待的队列
  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值