privatestaticbooleanshouldParkAfterFailedAcquire(Node pred, Node node) { intws= pred.waitStatus; if (ws == Node.SIGNAL) // 如果前驱节点为Single,则表明前驱节点已经被阻塞了。则当前节点就能够安全的被阻塞了。 returntrue; if (ws > 0) { // 如果前驱节点已经被取消了,则将被取消的节点移出队列。然后返回false do { node.prev = pred = pred.prev; } while (pred.waitStatus > 0); pred.next = node; } else { /* * waitStatus must be 0 or PROPAGATE. Indicate that we * need a signal, but don't park yet. Caller will need to * retry to make sure it cannot acquire before parking. */ // 将前驱节点设置为Signal,然后返回false。因为前驱节点为signal的时候,在其release的时候会通知后续节点唤醒。 compareAndSetWaitStatus(pred, ws, Node.SIGNAL); } returnfalse; }
privatevoidunparkSuccessor(Node node) { /* * If status is negative (i.e., possibly needing signal) try * to clear in anticipation of signalling. It is OK if this * fails or if status is changed by waiting thread. */ intws= node.waitStatus; if (ws < 0) compareAndSetWaitStatus(node, ws, 0);
Nodes= node.next; // 默认唤醒下一个节点,如果下一个节点已经取消或者为空,则从尾部找到一个没有被取消的节点唤醒。 if (s == null || s.waitStatus > 0) { s = null; for (Nodet= tail; t != null && t != node; t = t.prev) if (t.waitStatus <= 0) s = t; } if (s != null) LockSupport.unpark(s.thread); }
finalbooleantransferForSignal(Node node) { /* *如果当前节点状态无法被替换,那么当前节点就被取消了 */ if (!node.compareAndSetWaitStatus(Node.CONDITION, 0)) returnfalse;
/* * Splice onto queue and try to set waitStatus of predecessor to * indicate that thread is (probably) waiting. If cancelled or * attempt to set waitStatus fails, wake up to resync (in which * case the waitStatus can be transiently and harmlessly wrong). */ // 将当前节点添加到同步队列并且返回前驱节点 Nodep= enq(node); intws= p.waitStatus; // 如果当前节点的前驱节点被取消了或尝试替换等待状态失败就唤醒当前线程。 // 前者:如果同步状态为取消,则唤醒线程,在await()逻辑中,被唤醒的线程会检查线程状态,此时的取消会导致在transferAfterCancelledWait()方法中,无法将node状态由CONDITION转为0,也就进而不停让出线程cpu时间,导致线程被取消。 // 后者:无法更改等待状态的值,就说明有其他线程在操作该node。 if (ws > 0 || !p.compareAndSetWaitStatus(ws, Node.SIGNAL)) LockSupport.unpark(node.thread); returntrue; }