我们需要一个通知信号,主要是因为当前线程要被挂起了(park)。 而如果waitStatus已经是’SIGNAL’的话就无需修改,直接挂起就好, 而如果waitStatus是’CANCELLED’的话,说明prev已经被取消了,是个无效节点了,那么无需修改这个无效节点的waitStatus,而是需要先找到一个有效的prev。 因此,剩下的情况就只有当waitStatus为’0’和’PROPAGAET’了(注意,waitStatus为’CONDITION’是节点不在等待队列中,所以当下情况waitStatus不可能为’CONDITION’),这时我们需要将prev的waitStatus使用CAS的方式修改为’SIGNAL’,而且只有修改成功的情况下,当前的线程才能安全被挂起。 还值得注意的时,因此该方法的CAS操作都是没有自旋的,所以当它操作完CAS后都会返回false,在外层的方法中会使用自旋,当发现返回的是false时,会再次调用该方法,以检查保证有当前node有一个有效的prev,并且其waitStatus为’SIGNAL’,在此情况下当前的线程才会被挂起(park)。
源码分析未完待续 下篇文章继续分析
DEMO代码链接
https://gitee.com/pingfanrenbiji/myconcurrent/tree/master/src/main/java/pers/hanchao/concurrent/eg14
参考文章
https://www.jianshu.com/p/9ee0194d598c