JUC之AbstractQueuedSynchronizer-ConditionObject

更多关于AbstractQueuedSynchronizer介绍,请戳《JUC之AbstractQueuedSynchronizer基本介绍》、《JUC之AbstractQueuedSynchronizer共享模式》。


AbstractQueuedSynchronizer中提供一个内部类ConditionObject用于模拟线程等待(wait)和唤醒(notify)的功能。ConditionObject中提供一个等待队列用于存放等待状态的线程,提供await方法用于将当前线程加入到等待队列中,提供signal方法用于唤醒线程将其从等待队列中移除。和Synchronized类比,await相当于Object中wait,signal相当于Object中notify,所以当前线程在使用await和signal方法的时候,也必须要持有AbstractQueuedSynchronizer提供的锁(通过acquire方法成功获取到锁)。

 


█ 等待队列

ConditionObject中也提供了一个等待队列,AbstractQueuedSynchronizer中的等待队列也可以叫同步队列,队列中的线程在等待获取锁。在ConditionObject的等待队列中的线程是先前已经获取到锁了,自己主动放弃锁进入等待队列,等待某个持有锁的线程将其唤醒或者自己主动唤醒(超时等待)。

private transient Node firstWaiter;

private transient Node lastWaiter;

通过firstWaiter指向等待队列中的第一个等待节点,lastWaiter指定等待队列中的最后一个节点。节点与节点之间通过前一个节点的nextWaiter指向下一个节点。所以不同于AbstractQueuedSynchronizer中的等待队列(同步队列)是双向的,ConditionObject中的等待队列是单向链表。这里的firstWaiter、lastWaiter与AbstractQueuedSynchronizer中的head、tail意思是一样的。


█ await

持有锁的线程调用await方法将会主动放弃锁,将其加入等待队列中。

public final void await() throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    // 将当前线程封装成node对象添加到等待队列中    
    Node node = addConditionWaiter();
    int savedState = fullyRelease(node);
    int interruptMode = 0;
    while (!isOnSyncQueue(node)) {
        LockSupport.park(this);
        if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
            break;
    }
    if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
        interruptMode = REINTERRUPT;
    if (node.nextWaiter != null) // clean up if cancelled
        unlinkCancelledWaiters();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值