一个封锁操作被对 wsacancelblockingcall 的调用中断_Java显式锁的中断、条件队列的排队与唤醒源码分析...

本文深入探讨了ReentrantLock的lock和lockInterruptibly的区别,分析了中断和非中断加锁模式的实现原理。lockInterruptibly在中断时会抛出InterruptedException,而lock则会忽略中断并继续尝试获取锁。同时,文章讲解了newCondition创建的条件队列,阐述了条件队列在等待和唤醒操作中的角色,以及其在多条件等待场景中的重要性。
摘要由CSDN通过智能技术生成

引言

上一节介绍了 ReentrantLock 类的 lock 锁获取流程,本节继续来说说它的其他两个知识点:

  • lock 和 lockInterruptibly 的区别
  • newCondition() ,条件队列的实现逻辑

lock 和 lockInterruptibly 的区别

ReentrantLock 的 lock 方法有几种获取锁方式:

  1. tryLock(),tryLock(long ,TimeUnit) ,可轮询的、可定时地获取锁;
  2. lock() ,无条件地轮询获取锁,锁等待期间,线程可被中断;
  3. lockInterruptibly() ,可中断的锁获取方式,锁等待期间,线程可被中断。

lock() 和 lockInterruptibly() ,这两个方法都能响应中断请求,但是区别在哪里呢?

分析源码,笔者发现 lock 方法默认处理了中断请求,一旦监测到中断状态,则中断当前线程;而 lockInterruptibly() 则直接抛出中断异常,由上层调用者区去处理中断,一起来看看源码细节。

lock 源码

lock 方法在获取锁的过程中,忽略了中断,并在成功获取锁之后,再根据中断标识处理中断,即 selfInterrupt 中断自己。 再回忆下 acquire 的源码:

/**  *默认处理中断方式是selfInterrupt */public final void acquire(int arg) {    if (!tryAcquire(arg) &&        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))        selfInterrupt();}

acquireQueued,在 for 循环中无条件重试获取锁,直到成功,同时返回线程中断状态。for 循正常返回时,必定是成功获取到了锁,它的源码是这样:

/** *无条件重试,直到成功返回,并且记录中断状态 */final boolean acquireQueued(final Node node, int arg) {    boolean failed = true;    try {        boolean interrupted = fa
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值