AQS之条件等待模式

本文详细介绍了AQS同步器中的条件等待模式,包括Condition的await、signal和signalAll方法。通过分析AQS的内部类ConditionObject,揭示了线程如何进入条件等待队列、释放同步状态以及唤醒等待线程的机制。此外,文章还探讨了线程中断和删除已取消等待节点的处理。最后,总结了条件等待的关键步骤,并预告了后续将学习的并发工具类。
摘要由CSDN通过智能技术生成

​基本介绍

 

勾勾在学习多线程基础知识的时候,学习了Object的wait和notify方法,这对组合可以使线程进入阻塞并由其他线程唤醒,但是notify的唤醒不能明确线程。在实际的工作中,各个业务之间有明确的等待关系,那么在唤醒的时候就需要唤醒特定的线程。

AQS同步器提供了条件等待的实现类Condition,在Condition对象中与wait、notify、notifyAll对应的方法是await、signal、signalAll。今天的文章我们依然撇开Condition本身的实现原理先了解AQS底层的条件等待的实现机制。

AQS维护了内部类ConditionObject,其实现了Condition接口。源码关键信息如下:

 public class ConditionObject implements Condition, java.io.Serializable {
        private static final long serialVersionUID = 1173984872572414699L;
        /** 条件等待队列中的第一个节点 */
        private transient Node firstWaiter;
        /** 条件等待队列中的最后一个节点*/
        private transient Node lastWaiter;

        /**
         * 无参构造
         */
        public ConditionObject() { }
       /** 在退出wait方法的时候重新打断线程 */
      private static final int REINTERRUPT =  1;
      /**退出await方法的时候抛出异常*/
      private static final int THROW_IE    = -1;
     ...
 }

 

条件等待.获取操作

 

ConditionObject类重写了Condition定义的await方法。

public final void await() throws InterruptedException {
     //await是可中断方法,当线程被打断后会抛出InterruptedException异常
     if (Thread.interrupted())
         throw new InterruptedException();
     //将当前线程节点添加至等待队列尾部,并设置其节点的waitStatus为CONDITION
     Node node = addConditionWaiter();
     //释放所有的同步器状态,并返回state的值
     int savedState = fullyRelease(node);
     int interruptMode = 0;
     //如果node不在同步等待队列中,则挂起当前线程
     while (!isOnSyncQueue(node)) {
         LockSupport.park(this);
         //如果线程被打断了则退出循环
         if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
             break;
     }
     //如果node在同步等待队列中,则调用acquireQueued不断尝试获取同步器状态,如果acquireQueued返回中断标志为true且interruptMode不等于-1,则将interruptMode修改为1
     if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
         interruptMode = REINTERRUPT;
    //如果节点的nextWaiter不为空,则移除队列中不是CONDITION状态的节点
     if (node.nextWaiter != null) // clean up if cancelled
         unlinkCancelledWaiters();
    //如果interruptMode不为0,则在await之后返回中断信息
     if (interruptMode != 0)
         reportInterruptAfterWait(interruptMode);
 }

private void reportInterruptAfterWait(int interruptMode)
     throws InterruptedException {
    //如果interruptMode为-1,则抛出异常
     if (interruptM
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值