/** * 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); } }
final Node p = node.predecessor(); if (p == head && tryAcquire(arg, id)) { setHead(node);
/** * Acquires in exclusive interruptible mode. * * @param arg * the acquire argument */ private void doAcquireInterruptibly(int arg, Object id) throws InterruptedException { final Node node = addWaiter(Node.EXCLUSIVE); try { for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg, id)) { setHead(node); p.next = null; // help GC return; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) break; } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } // Arrive here only if interrupted cancelAcquire(node); throw new InterruptedException(); }
/** * Acquires in exclusive uninterruptible mode for thread already in queue. * Used by condition wait methods as well as acquire. * * @param node * the node * @param arg * the acquire argument * @return {@code true} if interrupted while waiting */ final boolean acquireQueued(final Node node, int arg, Object id) { try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg, id)) { setHead(node); p.next = null; // help GC return interrupted; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } }