详解AQS中的condition源码原理( 二 )

唤醒过程signal()
1.检查调用signal时,是否当前线程获取了锁,不是则抛异常
if (!isHeldExclusively()) throw new IllegalMonitorStateException();2.获取condition队列中的第一个等待节点
Node first = firstWaiter;if (first != null) doSignal(first);3.用CAS清除CONDITION状态
if (!node.compareAndSetWaitStatus(Node.CONDITION, 0)) return false;4.调用AQS的enq(firstWaitNode),将这个节点放入到同步队列的队尾(需要CAS支撑?因为可能是共享的,即使获取了锁也需要竞争)
Node p = enq(node);5.移动入同步队列成功后(可能经历了几次CAS),再用unpark方法唤醒,那个线程就进入了上面代码中Park之后的部分了
【详解AQS中的condition源码原理】int ws = p.waitStatus;if (ws > 0 || !p.compareAndSetWaitStatus(ws, Node.SIGNAL)) LockSupport.unpark(node.thread);6.如果是signalAll方法,则等待队列中每个节点都执行一次signal方法,全部移入同步队列中并唤醒(唤醒后他们很可能还会因为抢不到资源而阻塞,但队列位置不同了,也无法再通过sign唤醒了)
do { Node next = first.nextWaiter; first.nextWaiter = null; transferForSignal(first);first = next;} while (first != null);点击关注,第一时间了解华为云新鲜技术~

经验总结扩展阅读