知识卡片

挂起前要确认前驱

普通读书笔记卡 · 1529.b.1

内容

AQS 在线程真正 park 前会调用 shouldParkAfterFailedAcquire() 做挂起预判:找到有效前驱(跳过 CANCELLED 节点),只有前驱状态已设为 SIGNAL 才返回 true 允许挂起;若前驱还是初始值 0,本次只设为 SIGNAL 并返回 false,继续自旋——一般要执行两次才真正阻塞,避免了信号丢失。

参考来源

- 位置:《Java高并发核心编程.卷2,多线程、锁、JMM、JUC、高并发设计模式》第6章《AQS抽象同步器的核心原理》6.5.7节《挂起预判:shouldParkAfterFailedAcquire()》、6.5.8节《线程挂起:parkAndCheckInterrupt()》(源文件:_epub-src/OEBPS/Text/chapter206.xhtml、chapter207.xhtml) - 结论依据:原文说明该方法“将当前节点的有效前驱节点……找到,并且将有效前驱节点的状态设置为SIGNAL,之后返回true代表当前线程可以马上被阻塞了”,并指出“此方法返回false时acquireQueued()不会阻塞当前线程,只有此方法返回true时当前线程才阻塞,因此在一般情况下,此方法至少需要执行两次,当前线程才会被阻塞”,因此推出本卡结论。 - 原始内容:shouldParkAfterFailedAcquire()方法的主要功能是:将当前节点的有效前驱节点……找到,并且将有效前驱节点的状态设置为SIGNAL,之后返回true代表当前线程可以马上被阻塞了……此方法至少需要执行两次,当前线程才会被阻塞。