//检查并更新无法获取的节点的状态。如果线程应该被阻塞,返回true privatestaticbooleanshouldParkAfterFailedAcquire(Node pred, Node node){ int ws = pred.waitStatus;//获取当前节点的前驱节点的等待状态。 /** * //当前节点的线程被取消 * static final int CANCELLED = 1; * //后继节点的线程需要被唤醒 * static final int SIGNAL = -1; * //表示当前节点的线程正在等待某个条件 * static final int CONDITION = -2; * // 表示接下来的一个共享模式请求(acquireShared)要无条件的传递(往后继节点方向)下去 * static final int PROPAGATE = -3; */ if (ws == Node.SIGNAL) //只有当前节点的前一个节点的等待状态为SIGNAL时,当前节点才能被挂起。 /* * This node has already set status asking a release * to signal it, so it can safely park. */ /* * 如果当前节点的前驱节点的状态为SIGNAL,说明当前节点已经声明了需要被唤醒, * 所以可以阻塞当前节点了,直接返回true。 * 一个节点在其被阻塞之前需要线程"声明"一下其需要唤醒(就是将其前驱节点 * 的等待状态设置为SIGNAL,注意其前驱节点不能是取消状态,如果是,要跳过) */ returntrue; if (ws > 0) { /* * Predecessor was cancelled. Skip over predecessors and * indicate retry. * 如果前驱节点的状态为取消,则跳过并重试 */ do { //循环跳过状态为CANCELLED的节点 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. */ 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. */ int ws = node.waitStatus; if (ws < 0) compareAndSetWaitStatus(node, ws, 0);
/* * Thread to unpark is held in successor, which is normally * just the next node. But if cancelled or apparently null, * traverse backwards from tail to find the actual * non-cancelled successor. * * 需被唤醒的线程在后继节点中,正常情况的话被唤醒的节点将是是下一个节点。如果下一个节点是取消状态或者为null的话,将从节点尾部开始寻找,知道找到未取消的节点。 */ Node s = node.next; if (s == null || s.waitStatus > 0) { s = null; for (Node t = tail; t != null && t != node; t = t.prev) //寻找的顺序是从队列尾部开始往前去找的最前面的一个waitStatus小于0的节点。 if (t.waitStatus <= 0) s = t; } if (s != null) LockSupport.unpark(s.thread); //唤醒线程 }