/** * Acquires in exclusive mode, ignoring interrupts. Implemented by invoking at * least once {@link #tryAcquire}, returning on success. Otherwise the thread * is queued, possibly repeatedly blocking and unblocking, invoking * {@link #tryAcquire} until success. * * @param arg * the acquire argument. This value is conveyed to * {@link #tryAcquire} but is otherwise uninterpreted and can * represent anything you like. */ public final void acquire(int arg, Object id) { if (!tryAcquire(arg, id) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg, id)) selfInterrupt(); }
/** * Acquires in shared uninterruptible mode. * * @param arg * the acquire argument */ private void doAcquireShared(int arg, Object id) { final Node node = addWaiter(Node.SHARED); try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head) { int r = tryAcquireShared(arg, id); if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC if (interrupted) selfInterrupt(); return; } } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } }