/** * Releases in exclusive mode. Implemented by unblocking one or more threads * * @param arg * the release argument. This value is conveyed to * {@link #tryRelease} but is otherwise uninterpreted and can * represent anything you like. * @return the value returned from {@link #tryRelease} */ public final boolean release(int arg, Object id) { if (tryRelease(arg, id)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; }
/** * Releases in shared mode. Implemented by unblocking one or more threads if * {@link #tryReleaseShared} returns true. * * @param arg * the release argument. This value is conveyed to * {@link #tryReleaseShared} but is otherwise uninterpreted and can * represent anything you like. * @return the value returned from {@link #tryReleaseShared} */ public final boolean releaseShared(int arg, Object id) { if (tryReleaseShared(arg, id)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; }
/** * Sets head of queue, and checks if successor may be waiting in shared mode, * if so propagating if propagate > 0. * * @param node * the node * @param propagate * the return value from a tryAcquireShared */ private void setHeadAndPropagate(Node node, int propagate) { setHead(node); if (propagate > 0 && node.waitStatus != 0) { /* * Don't bother fully figuring out successor. If it * looks null, call unparkSuccessor anyway to be safe. */ Node s = node.next; if (s == null || s.isShared()) unparkSuccessor(node); } }