summaryrefslogtreecommitdiff
path: root/libjava/classpath/external/jsr166/java/util/concurrent/locks
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/external/jsr166/java/util/concurrent/locks
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/classpath/external/jsr166/java/util/concurrent/locks')
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractOwnableSynchronizer.java57
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java1934
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedSynchronizer.java2159
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/locks/Condition.java435
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/locks/Lock.java327
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/locks/LockSupport.java352
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/locks/ReadWriteLock.java104
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantLock.java740
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantReadWriteLock.java1346
9 files changed, 7454 insertions, 0 deletions
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractOwnableSynchronizer.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractOwnableSynchronizer.java
new file mode 100644
index 000000000..f3780e5a6
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractOwnableSynchronizer.java
@@ -0,0 +1,57 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+
+/**
+ * A synchronizer that may be exclusively owned by a thread. This
+ * class provides a basis for creating locks and related synchronizers
+ * that may entail a notion of ownership. The
+ * <tt>AbstractOwnableSynchronizer</tt> class itself does not manage or
+ * use this information. However, subclasses and tools may use
+ * appropriately maintained values to help control and monitor access
+ * and provide diagnostics.
+ *
+ * @since 1.6
+ * @author Doug Lea
+ */
+public abstract class AbstractOwnableSynchronizer
+ implements java.io.Serializable {
+
+ /** Use serial ID even though all fields transient. */
+ private static final long serialVersionUID = 3737899427754241961L;
+
+ /**
+ * Empty constructor for use by subclasses.
+ */
+ protected AbstractOwnableSynchronizer() { }
+
+ /**
+ * The current owner of exclusive mode synchronization.
+ */
+ private transient Thread exclusiveOwnerThread;
+
+ /**
+ * Sets the thread that currently owns exclusive access. A
+ * <tt>null</tt> argument indicates that no thread owns access.
+ * This method does not otherwise impose any synchronization or
+ * <tt>volatile</tt> field accesses.
+ */
+ protected final void setExclusiveOwnerThread(Thread t) {
+ exclusiveOwnerThread = t;
+ }
+
+ /**
+ * Returns the thread last set by
+ * <tt>setExclusiveOwnerThread</tt>, or <tt>null</tt> if never
+ * set. This method does not otherwise impose any synchronization
+ * or <tt>volatile</tt> field accesses.
+ * @return the owner thread
+ */
+ protected final Thread getExclusiveOwnerThread() {
+ return exclusiveOwnerThread;
+ }
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
new file mode 100644
index 000000000..45d744bb8
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
@@ -0,0 +1,1934 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import sun.misc.Unsafe;
+
+/**
+ * A version of {@link AbstractQueuedSynchronizer} in
+ * which synchronization state is maintained as a <tt>long</tt>.
+ * This class has exactly the same structure, properties, and methods
+ * as <tt>AbstractQueuedSynchronizer</tt> with the exception
+ * that all state-related parameters and results are defined
+ * as <tt>long</tt> rather than <tt>int</tt>. This class
+ * may be useful when creating synchronizers such as
+ * multilevel locks and barriers that require
+ * 64 bits of state.
+ *
+ * <p>See {@link AbstractQueuedSynchronizer} for usage
+ * notes and examples.
+ *
+ * @since 1.6
+ * @author Doug Lea
+ */
+public abstract class AbstractQueuedLongSynchronizer
+ extends AbstractOwnableSynchronizer
+ implements java.io.Serializable {
+
+ private static final long serialVersionUID = 7373984972572414692L;
+
+ /*
+ To keep sources in sync, the remainder of this source file is
+ exactly cloned from AbstractQueuedSynchronizer, replacing class
+ name and changing ints related with sync state to longs. Please
+ keep it that way.
+ */
+
+ /**
+ * Creates a new <tt>AbstractQueuedLongSynchronizer</tt> instance
+ * with initial synchronization state of zero.
+ */
+ protected AbstractQueuedLongSynchronizer() { }
+
+ /**
+ * Wait queue node class.
+ *
+ * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and
+ * Hagersten) lock queue. CLH locks are normally used for
+ * spinlocks. We instead use them for blocking synchronizers, but
+ * use the same basic tactic of holding some of the control
+ * information about a thread in the predecessor of its node. A
+ * "status" field in each node keeps track of whether a thread
+ * should block. A node is signalled when its predecessor
+ * releases. Each node of the queue otherwise serves as a
+ * specific-notification-style monitor holding a single waiting
+ * thread. The status field does NOT control whether threads are
+ * granted locks etc though. A thread may try to acquire if it is
+ * first in the queue. But being first does not guarantee success;
+ * it only gives the right to contend. So the currently released
+ * contender thread may need to rewait.
+ *
+ * <p>To enqueue into a CLH lock, you atomically splice it in as new
+ * tail. To dequeue, you just set the head field.
+ * <pre>
+ * +------+ prev +-----+ +-----+
+ * head | | <---- | | <---- | | tail
+ * +------+ +-----+ +-----+
+ * </pre>
+ *
+ * <p>Insertion into a CLH queue requires only a single atomic
+ * operation on "tail", so there is a simple atomic point of
+ * demarcation from unqueued to queued. Similarly, dequeing
+ * involves only updating the "head". However, it takes a bit
+ * more work for nodes to determine who their successors are,
+ * in part to deal with possible cancellation due to timeouts
+ * and interrupts.
+ *
+ * <p>The "prev" links (not used in original CLH locks), are mainly
+ * needed to handle cancellation. If a node is cancelled, its
+ * successor is (normally) relinked to a non-cancelled
+ * predecessor. For explanation of similar mechanics in the case
+ * of spin locks, see the papers by Scott and Scherer at
+ * http://www.cs.rochester.edu/u/scott/synchronization/
+ *
+ * <p>We also use "next" links to implement blocking mechanics.
+ * The thread id for each node is kept in its own node, so a
+ * predecessor signals the next node to wake up by traversing
+ * next link to determine which thread it is. Determination of
+ * successor must avoid races with newly queued nodes to set
+ * the "next" fields of their predecessors. This is solved
+ * when necessary by checking backwards from the atomically
+ * updated "tail" when a node's successor appears to be null.
+ * (Or, said differently, the next-links are an optimization
+ * so that we don't usually need a backward scan.)
+ *
+ * <p>Cancellation introduces some conservatism to the basic
+ * algorithms. Since we must poll for cancellation of other
+ * nodes, we can miss noticing whether a cancelled node is
+ * ahead or behind us. This is dealt with by always unparking
+ * successors upon cancellation, allowing them to stabilize on
+ * a new predecessor.
+ *
+ * <p>CLH queues need a dummy header node to get started. But
+ * we don't create them on construction, because it would be wasted
+ * effort if there is never contention. Instead, the node
+ * is constructed and head and tail pointers are set upon first
+ * contention.
+ *
+ * <p>Threads waiting on Conditions use the same nodes, but
+ * use an additional link. Conditions only need to link nodes
+ * in simple (non-concurrent) linked queues because they are
+ * only accessed when exclusively held. Upon await, a node is
+ * inserted into a condition queue. Upon signal, the node is
+ * transferred to the main queue. A special value of status
+ * field is used to mark which queue a node is on.
+ *
+ * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill
+ * Scherer and Michael Scott, along with members of JSR-166
+ * expert group, for helpful ideas, discussions, and critiques
+ * on the design of this class.
+ */
+ static final class Node {
+ /** waitStatus value to indicate thread has cancelled */
+ static final int CANCELLED = 1;
+ /** waitStatus value to indicate successor's thread needs unparking */
+ static final int SIGNAL = -1;
+ /** waitStatus value to indicate thread is waiting on condition */
+ static final int CONDITION = -2;
+ /** Marker to indicate a node is waiting in shared mode */
+ static final Node SHARED = new Node();
+ /** Marker to indicate a node is waiting in exclusive mode */
+ static final Node EXCLUSIVE = null;
+
+ /**
+ * Status field, taking on only the values:
+ * SIGNAL: The successor of this node is (or will soon be)
+ * blocked (via park), so the current node must
+ * unpark its successor when it releases or
+ * cancels. To avoid races, acquire methods must
+ * first indicate they need a signal,
+ * then retry the atomic acquire, and then,
+ * on failure, block.
+ * CANCELLED: This node is cancelled due to timeout or interrupt.
+ * Nodes never leave this state. In particular,
+ * a thread with cancelled node never again blocks.
+ * CONDITION: This node is currently on a condition queue.
+ * It will not be used as a sync queue node until
+ * transferred. (Use of this value here
+ * has nothing to do with the other uses
+ * of the field, but simplifies mechanics.)
+ * 0: None of the above
+ *
+ * The values are arranged numerically to simplify use.
+ * Non-negative values mean that a node doesn't need to
+ * signal. So, most code doesn't need to check for particular
+ * values, just for sign.
+ *
+ * The field is initialized to 0 for normal sync nodes, and
+ * CONDITION for condition nodes. It is modified only using
+ * CAS.
+ */
+ volatile int waitStatus;
+
+ /**
+ * Link to predecessor node that current node/thread relies on
+ * for checking waitStatus. Assigned during enqueing, and nulled
+ * out (for sake of GC) only upon dequeuing. Also, upon
+ * cancellation of a predecessor, we short-circuit while
+ * finding a non-cancelled one, which will always exist
+ * because the head node is never cancelled: A node becomes
+ * head only as a result of successful acquire. A
+ * cancelled thread never succeeds in acquiring, and a thread only
+ * cancels itself, not any other node.
+ */
+ volatile Node prev;
+
+ /**
+ * Link to the successor node that the current node/thread
+ * unparks upon release. Assigned once during enqueuing, and
+ * nulled out (for sake of GC) when no longer needed. Upon
+ * cancellation, we cannot adjust this field, but can notice
+ * status and bypass the node if cancelled. The enq operation
+ * does not assign next field of a predecessor until after
+ * attachment, so seeing a null next field does not
+ * necessarily mean that node is at end of queue. However, if
+ * a next field appears to be null, we can scan prev's from
+ * the tail to double-check.
+ */
+ volatile Node next;
+
+ /**
+ * The thread that enqueued this node. Initialized on
+ * construction and nulled out after use.
+ */
+ volatile Thread thread;
+
+ /**
+ * Link to next node waiting on condition, or the special
+ * value SHARED. Because condition queues are accessed only
+ * when holding in exclusive mode, we just need a simple
+ * linked queue to hold nodes while they are waiting on
+ * conditions. They are then transferred to the queue to
+ * re-acquire. And because conditions can only be exclusive,
+ * we save a field by using special value to indicate shared
+ * mode.
+ */
+ Node nextWaiter;
+
+ /**
+ * Returns true if node is waiting in shared mode
+ */
+ final boolean isShared() {
+ return nextWaiter == SHARED;
+ }
+
+ /**
+ * Returns previous node, or throws NullPointerException if
+ * null. Use when predecessor cannot be null.
+ * @return the predecessor of this node
+ */
+ final Node predecessor() throws NullPointerException {
+ Node p = prev;
+ if (p == null)
+ throw new NullPointerException();
+ else
+ return p;
+ }
+
+ Node() { // Used to establish initial head or SHARED marker
+ }
+
+ Node(Thread thread, Node mode) { // Used by addWaiter
+ this.nextWaiter = mode;
+ this.thread = thread;
+ }
+
+ Node(Thread thread, int waitStatus) { // Used by Condition
+ this.waitStatus = waitStatus;
+ this.thread = thread;
+ }
+ }
+
+ /**
+ * Head of the wait queue, lazily initialized. Except for
+ * initialization, it is modified only via method setHead. Note:
+ * If head exists, its waitStatus is guaranteed not to be
+ * CANCELLED.
+ */
+ private transient volatile Node head;
+
+ /**
+ * Tail of the wait queue, lazily initialized. Modified only via
+ * method enq to add new wait node.
+ */
+ private transient volatile Node tail;
+
+ /**
+ * The synchronization state.
+ */
+ private volatile long state;
+
+ /**
+ * Returns the current value of synchronization state.
+ * This operation has memory semantics of a <tt>volatile</tt> read.
+ * @return current state value
+ */
+ protected final long getState() {
+ return state;
+ }
+
+ /**
+ * Sets the value of synchronization state.
+ * This operation has memory semantics of a <tt>volatile</tt> write.
+ * @param newState the new state value
+ */
+ protected final void setState(long newState) {
+ state = newState;
+ }
+
+ /**
+ * Atomically sets synchronization state to the given updated
+ * value if the current state value equals the expected value.
+ * This operation has memory semantics of a <tt>volatile</tt> read
+ * and write.
+ *
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that the actual
+ * value was not equal to the expected value.
+ */
+ protected final boolean compareAndSetState(long expect, long update) {
+ // See below for intrinsics setup to support this
+ return unsafe.compareAndSwapLong(this, stateOffset, expect, update);
+ }
+
+ // Queuing utilities
+
+ /**
+ * The number of nanoseconds for which it is faster to spin
+ * rather than to use timed park. A rough estimate suffices
+ * to improve responsiveness with very short timeouts.
+ */
+ static final long spinForTimeoutThreshold = 1000L;
+
+ /**
+ * Inserts node into queue, initializing if necessary. See picture above.
+ * @param node the node to insert
+ * @return node's predecessor
+ */
+ private Node enq(final Node node) {
+ for (;;) {
+ Node t = tail;
+ if (t == null) { // Must initialize
+ Node h = new Node(); // Dummy header
+ h.next = node;
+ node.prev = h;
+ if (compareAndSetHead(h)) {
+ tail = node;
+ return h;
+ }
+ }
+ else {
+ node.prev = t;
+ if (compareAndSetTail(t, node)) {
+ t.next = node;
+ return t;
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates and enqueues node for given thread and mode.
+ *
+ * @param current the thread
+ * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
+ * @return the new node
+ */
+ private Node addWaiter(Node mode) {
+ Node node = new Node(Thread.currentThread(), mode);
+ // Try the fast path of enq; backup to full enq on failure
+ Node pred = tail;
+ if (pred != null) {
+ node.prev = pred;
+ if (compareAndSetTail(pred, node)) {
+ pred.next = node;
+ return node;
+ }
+ }
+ enq(node);
+ return node;
+ }
+
+ /**
+ * Sets head of queue to be node, thus dequeuing. Called only by
+ * acquire methods. Also nulls out unused fields for sake of GC
+ * and to suppress unnecessary signals and traversals.
+ *
+ * @param node the node
+ */
+ private void setHead(Node node) {
+ head = node;
+ node.thread = null;
+ node.prev = null;
+ }
+
+ /**
+ * Wakes up node's successor, if one exists.
+ *
+ * @param node the node
+ */
+ private void unparkSuccessor(Node node) {
+ /*
+ * Try to clear status in anticipation of signalling. It is
+ * OK if this fails or if status is changed by waiting thread.
+ */
+ compareAndSetWaitStatus(node, Node.SIGNAL, 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.
+ */
+ Node s = node.next;
+ if (s == null || s.waitStatus > 0) {
+ s = null;
+ for (Node t = tail; t != null && t != node; t = t.prev)
+ if (t.waitStatus <= 0)
+ s = t;
+ }
+ if (s != null)
+ LockSupport.unpark(s.thread);
+ }
+
+ /**
+ * Sets head of queue, and checks if successor may be waiting
+ * in shared mode, if so propagating if propagate > 0.
+ *
+ * @param pred the node holding waitStatus for node
+ * @param node the node
+ * @param propagate the return value from a tryAcquireShared
+ */
+ private void setHeadAndPropagate(Node node, long 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);
+ }
+ }
+
+ // Utilities for various versions of acquire
+
+ /**
+ * Cancels an ongoing attempt to acquire.
+ *
+ * @param node the node
+ */
+ private void cancelAcquire(Node node) {
+ if (node != null) { // Ignore if node doesn't exist
+ node.thread = null;
+ // Can use unconditional write instead of CAS here
+ node.waitStatus = Node.CANCELLED;
+ unparkSuccessor(node);
+ }
+ }
+
+ /**
+ * Checks and updates status for a node that failed to acquire.
+ * Returns true if thread should block. This is the main signal
+ * control in all acquire loops. Requires that pred == node.prev
+ *
+ * @param pred node's predecessor holding status
+ * @param node the node
+ * @return {@code true} if thread should block
+ */
+ private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
+ int s = pred.waitStatus;
+ if (s < 0)
+ /*
+ * This node has already set status asking a release
+ * to signal it, so it can safely park
+ */
+ return true;
+ if (s > 0)
+ /*
+ * Predecessor was cancelled. Move up to its predecessor
+ * and indicate retry.
+ */
+ node.prev = pred.prev;
+ else
+ /*
+ * 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, 0, Node.SIGNAL);
+ return false;
+ }
+
+ /**
+ * Convenience method to interrupt current thread.
+ */
+ private static void selfInterrupt() {
+ Thread.currentThread().interrupt();
+ }
+
+ /**
+ * Convenience method to park and then check if interrupted
+ *
+ * @return {@code true} if interrupted
+ */
+ private final boolean parkAndCheckInterrupt() {
+ LockSupport.park(this);
+ return Thread.interrupted();
+ }
+
+ /*
+ * Various flavors of acquire, varying in exclusive/shared and
+ * control modes. Each is mostly the same, but annoyingly
+ * different. Only a little bit of factoring is possible due to
+ * interactions of exception mechanics (including ensuring that we
+ * cancel if tryAcquire throws exception) and other control, at
+ * least not without hurting performance too much.
+ */
+
+ /**
+ * 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, long arg) {
+ try {
+ boolean interrupted = false;
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head && tryAcquire(arg)) {
+ setHead(node);
+ p.next = null; // help GC
+ return interrupted;
+ }
+ if (shouldParkAfterFailedAcquire(p, node) &&
+ parkAndCheckInterrupt())
+ interrupted = true;
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ }
+
+ /**
+ * Acquires in exclusive interruptible mode.
+ * @param arg the acquire argument
+ */
+ private void doAcquireInterruptibly(long arg)
+ throws InterruptedException {
+ final Node node = addWaiter(Node.EXCLUSIVE);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head && tryAcquire(arg)) {
+ 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 timed mode.
+ *
+ * @param arg the acquire argument
+ * @param nanosTimeout max wait time
+ * @return {@code true} if acquired
+ */
+ private boolean doAcquireNanos(long arg, long nanosTimeout)
+ throws InterruptedException {
+ long lastTime = System.nanoTime();
+ final Node node = addWaiter(Node.EXCLUSIVE);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head && tryAcquire(arg)) {
+ setHead(node);
+ p.next = null; // help GC
+ return true;
+ }
+ if (nanosTimeout <= 0) {
+ cancelAcquire(node);
+ return false;
+ }
+ if (nanosTimeout > spinForTimeoutThreshold &&
+ shouldParkAfterFailedAcquire(p, node))
+ LockSupport.parkNanos(this, nanosTimeout);
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ if (Thread.interrupted())
+ break;
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ // Arrive here only if interrupted
+ cancelAcquire(node);
+ throw new InterruptedException();
+ }
+
+ /**
+ * Acquires in shared uninterruptible mode.
+ * @param arg the acquire argument
+ */
+ private void doAcquireShared(long arg) {
+ final Node node = addWaiter(Node.SHARED);
+ try {
+ boolean interrupted = false;
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head) {
+ long r = tryAcquireShared(arg);
+ 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;
+ }
+ }
+
+ /**
+ * Acquires in shared interruptible mode.
+ * @param arg the acquire argument
+ */
+ private void doAcquireSharedInterruptibly(long arg)
+ throws InterruptedException {
+ final Node node = addWaiter(Node.SHARED);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head) {
+ long r = tryAcquireShared(arg);
+ if (r >= 0) {
+ setHeadAndPropagate(node, r);
+ 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 shared timed mode.
+ *
+ * @param arg the acquire argument
+ * @param nanosTimeout max wait time
+ * @return {@code true} if acquired
+ */
+ private boolean doAcquireSharedNanos(long arg, long nanosTimeout)
+ throws InterruptedException {
+
+ long lastTime = System.nanoTime();
+ final Node node = addWaiter(Node.SHARED);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head) {
+ long r = tryAcquireShared(arg);
+ if (r >= 0) {
+ setHeadAndPropagate(node, r);
+ p.next = null; // help GC
+ return true;
+ }
+ }
+ if (nanosTimeout <= 0) {
+ cancelAcquire(node);
+ return false;
+ }
+ if (nanosTimeout > spinForTimeoutThreshold &&
+ shouldParkAfterFailedAcquire(p, node))
+ LockSupport.parkNanos(this, nanosTimeout);
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ if (Thread.interrupted())
+ break;
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ // Arrive here only if interrupted
+ cancelAcquire(node);
+ throw new InterruptedException();
+ }
+
+ // Main exported methods
+
+ /**
+ * Attempts to acquire in exclusive mode. This method should query
+ * if the state of the object permits it to be acquired in the
+ * exclusive mode, and if so to acquire it.
+ *
+ * <p>This method is always invoked by the thread performing
+ * acquire. If this method reports failure, the acquire method
+ * may queue the thread, if it is not already queued, until it is
+ * signalled by a release from some other thread. This can be used
+ * to implement method {@link Lock#tryLock()}.
+ *
+ * <p>The default
+ * implementation throws {@link UnsupportedOperationException}.
+ *
+ * @param arg the acquire argument. This value is always the one
+ * passed to an acquire method, or is the value saved on entry
+ * to a condition wait. The value is otherwise uninterpreted
+ * and can represent anything you like.
+ * @return {@code true} if successful. Upon success, this object has
+ * been acquired.
+ * @throws IllegalMonitorStateException if acquiring would place this
+ * synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if exclusive mode is not supported
+ */
+ protected boolean tryAcquire(long arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Attempts to set the state to reflect a release in exclusive
+ * mode.
+ *
+ * <p>This method is always invoked by the thread performing release.
+ *
+ * <p>The default implementation throws
+ * {@link UnsupportedOperationException}.
+ *
+ * @param arg the release argument. This value is always the one
+ * passed to a release method, or the current state value upon
+ * entry to a condition wait. The value is otherwise
+ * uninterpreted and can represent anything you like.
+ * @return {@code true} if this object is now in a fully released
+ * state, so that any waiting threads may attempt to acquire;
+ * and {@code false} otherwise.
+ * @throws IllegalMonitorStateException if releasing would place this
+ * synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if exclusive mode is not supported
+ */
+ protected boolean tryRelease(long arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Attempts to acquire in shared mode. This method should query if
+ * the state of the object permits it to be acquired in the shared
+ * mode, and if so to acquire it.
+ *
+ * <p>This method is always invoked by the thread performing
+ * acquire. If this method reports failure, the acquire method
+ * may queue the thread, if it is not already queued, until it is
+ * signalled by a release from some other thread.
+ *
+ * <p>The default implementation throws {@link
+ * UnsupportedOperationException}.
+ *
+ * @param arg the acquire argument. This value is always the one
+ * passed to an acquire method, or is the value saved on entry
+ * to a condition wait. The value is otherwise uninterpreted
+ * and can represent anything you like.
+ * @return a negative value on failure; zero if acquisition in shared
+ * mode succeeded but no subsequent shared-mode acquire can
+ * succeed; and a positive value if acquisition in shared
+ * mode succeeded and subsequent shared-mode acquires might
+ * also succeed, in which case a subsequent waiting thread
+ * must check availability. (Support for three different
+ * return values enables this method to be used in contexts
+ * where acquires only sometimes act exclusively.) Upon
+ * success, this object has been acquired.
+ * @throws IllegalMonitorStateException if acquiring would place this
+ * synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if shared mode is not supported
+ */
+ protected long tryAcquireShared(long arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Attempts to set the state to reflect a release in shared mode.
+ *
+ * <p>This method is always invoked by the thread performing release.
+ *
+ * <p>The default implementation throws
+ * {@link UnsupportedOperationException}.
+ *
+ * @param arg the release argument. This value is always the one
+ * passed to a release method, or the current state value upon
+ * entry to a condition wait. The value is otherwise
+ * uninterpreted and can represent anything you like.
+ * @return {@code true} if this release of shared mode may permit a
+ * waiting acquire (shared or exclusive) to succeed; and
+ * {@code false} otherwise
+ * @throws IllegalMonitorStateException if releasing would place this
+ * synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if shared mode is not supported
+ */
+ protected boolean tryReleaseShared(long arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns {@code true} if synchronization is held exclusively with
+ * respect to the current (calling) thread. This method is invoked
+ * upon each call to a non-waiting {@link ConditionObject} method.
+ * (Waiting methods instead invoke {@link #release}.)
+ *
+ * <p>The default implementation throws {@link
+ * UnsupportedOperationException}. This method is invoked
+ * internally only within {@link ConditionObject} methods, so need
+ * not be defined if conditions are not used.
+ *
+ * @return {@code true} if synchronization is held exclusively;
+ * {@code false} otherwise
+ * @throws UnsupportedOperationException if conditions are not supported
+ */
+ protected boolean isHeldExclusively() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * 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. This method can be used
+ * to implement method {@link Lock#lock}.
+ *
+ * @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(long arg) {
+ if (!tryAcquire(arg) &&
+ acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
+ selfInterrupt();
+ }
+
+ /**
+ * Acquires in exclusive mode, aborting if interrupted.
+ * Implemented by first checking interrupt status, then invoking
+ * at least once {@link #tryAcquire}, returning on
+ * success. Otherwise the thread is queued, possibly repeatedly
+ * blocking and unblocking, invoking {@link #tryAcquire}
+ * until success or the thread is interrupted. This method can be
+ * used to implement method {@link Lock#lockInterruptibly}.
+ *
+ * @param arg the acquire argument. This value is conveyed to
+ * {@link #tryAcquire} but is otherwise uninterpreted and
+ * can represent anything you like.
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final void acquireInterruptibly(long arg) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ if (!tryAcquire(arg))
+ doAcquireInterruptibly(arg);
+ }
+
+ /**
+ * Attempts to acquire in exclusive mode, aborting if interrupted,
+ * and failing if the given timeout elapses. Implemented by first
+ * checking interrupt status, then invoking at least once {@link
+ * #tryAcquire}, returning on success. Otherwise, the thread is
+ * queued, possibly repeatedly blocking and unblocking, invoking
+ * {@link #tryAcquire} until success or the thread is interrupted
+ * or the timeout elapses. This method can be used to implement
+ * method {@link Lock#tryLock(long, TimeUnit)}.
+ *
+ * @param arg the acquire argument. This value is conveyed to
+ * {@link #tryAcquire} but is otherwise uninterpreted and
+ * can represent anything you like.
+ * @param nanosTimeout the maximum number of nanoseconds to wait
+ * @return {@code true} if acquired; {@code false} if timed out
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final boolean tryAcquireNanos(long arg, long nanosTimeout) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ return tryAcquire(arg) ||
+ doAcquireNanos(arg, nanosTimeout);
+ }
+
+ /**
+ * Releases in exclusive mode. Implemented by unblocking one or
+ * more threads if {@link #tryRelease} returns true.
+ * This method can be used to implement method {@link Lock#unlock}.
+ *
+ * @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(long arg) {
+ if (tryRelease(arg)) {
+ Node h = head;
+ if (h != null && h.waitStatus != 0)
+ unparkSuccessor(h);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Acquires in shared mode, ignoring interrupts. Implemented by
+ * first invoking at least once {@link #tryAcquireShared},
+ * returning on success. Otherwise the thread is queued, possibly
+ * repeatedly blocking and unblocking, invoking {@link
+ * #tryAcquireShared} until success.
+ *
+ * @param arg the acquire argument. This value is conveyed to
+ * {@link #tryAcquireShared} but is otherwise uninterpreted
+ * and can represent anything you like.
+ */
+ public final void acquireShared(long arg) {
+ if (tryAcquireShared(arg) < 0)
+ doAcquireShared(arg);
+ }
+
+ /**
+ * Acquires in shared mode, aborting if interrupted. Implemented
+ * by first checking interrupt status, then invoking at least once
+ * {@link #tryAcquireShared}, returning on success. Otherwise the
+ * thread is queued, possibly repeatedly blocking and unblocking,
+ * invoking {@link #tryAcquireShared} until success or the thread
+ * is interrupted.
+ * @param arg the acquire argument.
+ * This value is conveyed to {@link #tryAcquireShared} but is
+ * otherwise uninterpreted and can represent anything
+ * you like.
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final void acquireSharedInterruptibly(long arg) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ if (tryAcquireShared(arg) < 0)
+ doAcquireSharedInterruptibly(arg);
+ }
+
+ /**
+ * Attempts to acquire in shared mode, aborting if interrupted, and
+ * failing if the given timeout elapses. Implemented by first
+ * checking interrupt status, then invoking at least once {@link
+ * #tryAcquireShared}, returning on success. Otherwise, the
+ * thread is queued, possibly repeatedly blocking and unblocking,
+ * invoking {@link #tryAcquireShared} until success or the thread
+ * is interrupted or the timeout elapses.
+ *
+ * @param arg the acquire argument. This value is conveyed to
+ * {@link #tryAcquireShared} but is otherwise uninterpreted
+ * and can represent anything you like.
+ * @param nanosTimeout the maximum number of nanoseconds to wait
+ * @return {@code true} if acquired; {@code false} if timed out
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final boolean tryAcquireSharedNanos(long arg, long nanosTimeout) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ return tryAcquireShared(arg) >= 0 ||
+ doAcquireSharedNanos(arg, nanosTimeout);
+ }
+
+ /**
+ * 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(long arg) {
+ if (tryReleaseShared(arg)) {
+ Node h = head;
+ if (h != null && h.waitStatus != 0)
+ unparkSuccessor(h);
+ return true;
+ }
+ return false;
+ }
+
+ // Queue inspection methods
+
+ /**
+ * Queries whether any threads are waiting to acquire. Note that
+ * because cancellations due to interrupts and timeouts may occur
+ * at any time, a {@code true} return does not guarantee that any
+ * other thread will ever acquire.
+ *
+ * <p>In this implementation, this operation returns in
+ * constant time.
+ *
+ * @return {@code true} if there may be other threads waiting to acquire
+ */
+ public final boolean hasQueuedThreads() {
+ return head != tail;
+ }
+
+ /**
+ * Queries whether any threads have ever contended to acquire this
+ * synchronizer; that is if an acquire method has ever blocked.
+ *
+ * <p>In this implementation, this operation returns in
+ * constant time.
+ *
+ * @return {@code true} if there has ever been contention
+ */
+ public final boolean hasContended() {
+ return head != null;
+ }
+
+ /**
+ * Returns the first (longest-waiting) thread in the queue, or
+ * {@code null} if no threads are currently queued.
+ *
+ * <p>In this implementation, this operation normally returns in
+ * constant time, but may iterate upon contention if other threads are
+ * concurrently modifying the queue.
+ *
+ * @return the first (longest-waiting) thread in the queue, or
+ * {@code null} if no threads are currently queued
+ */
+ public final Thread getFirstQueuedThread() {
+ // handle only fast path, else relay
+ return (head == tail)? null : fullGetFirstQueuedThread();
+ }
+
+ /**
+ * Version of getFirstQueuedThread called when fastpath fails
+ */
+ private Thread fullGetFirstQueuedThread() {
+ /*
+ * The first node is normally h.next. Try to get its
+ * thread field, ensuring consistent reads: If thread
+ * field is nulled out or s.prev is no longer head, then
+ * some other thread(s) concurrently performed setHead in
+ * between some of our reads. We try this twice before
+ * resorting to traversal.
+ */
+ Node h, s;
+ Thread st;
+ if (((h = head) != null && (s = h.next) != null &&
+ s.prev == head && (st = s.thread) != null) ||
+ ((h = head) != null && (s = h.next) != null &&
+ s.prev == head && (st = s.thread) != null))
+ return st;
+
+ /*
+ * Head's next field might not have been set yet, or may have
+ * been unset after setHead. So we must check to see if tail
+ * is actually first node. If not, we continue on, safely
+ * traversing from tail back to head to find first,
+ * guaranteeing termination.
+ */
+
+ Node t = tail;
+ Thread firstThread = null;
+ while (t != null && t != head) {
+ Thread tt = t.thread;
+ if (tt != null)
+ firstThread = tt;
+ t = t.prev;
+ }
+ return firstThread;
+ }
+
+ /**
+ * Returns true if the given thread is currently queued.
+ *
+ * <p>This implementation traverses the queue to determine
+ * presence of the given thread.
+ *
+ * @param thread the thread
+ * @return {@code true} if the given thread is on the queue
+ * @throws NullPointerException if the thread is null
+ */
+ public final boolean isQueued(Thread thread) {
+ if (thread == null)
+ throw new NullPointerException();
+ for (Node p = tail; p != null; p = p.prev)
+ if (p.thread == thread)
+ return true;
+ return false;
+ }
+
+ /**
+ * Return {@code true} if the apparent first queued thread, if one
+ * exists, is not waiting in exclusive mode. Used only as a heuristic
+ * in ReentrantReadWriteLock.
+ */
+ final boolean apparentlyFirstQueuedIsExclusive() {
+ Node h, s;
+ return ((h = head) != null && (s = h.next) != null &&
+ s.nextWaiter != Node.SHARED);
+ }
+
+ /**
+ * Return {@code true} if the queue is empty or if the given thread
+ * is at the head of the queue. This is reliable only if
+ * <tt>current</tt> is actually Thread.currentThread() of caller.
+ */
+ final boolean isFirst(Thread current) {
+ Node h, s;
+ return ((h = head) == null ||
+ ((s = h.next) != null && s.thread == current) ||
+ fullIsFirst(current));
+ }
+
+ final boolean fullIsFirst(Thread current) {
+ // same idea as fullGetFirstQueuedThread
+ Node h, s;
+ Thread firstThread = null;
+ if (((h = head) != null && (s = h.next) != null &&
+ s.prev == head && (firstThread = s.thread) != null))
+ return firstThread == current;
+ Node t = tail;
+ while (t != null && t != head) {
+ Thread tt = t.thread;
+ if (tt != null)
+ firstThread = tt;
+ t = t.prev;
+ }
+ return firstThread == current || firstThread == null;
+ }
+
+
+ // Instrumentation and monitoring methods
+
+ /**
+ * Returns an estimate of the number of threads waiting to
+ * acquire. The value is only an estimate because the number of
+ * threads may change dynamically while this method traverses
+ * internal data structures. This method is designed for use in
+ * monitoring system state, not for synchronization
+ * control.
+ *
+ * @return the estimated number of threads waiting to acquire
+ */
+ public final int getQueueLength() {
+ int n = 0;
+ for (Node p = tail; p != null; p = p.prev) {
+ if (p.thread != null)
+ ++n;
+ }
+ return n;
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire. Because the actual set of threads may change
+ * dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive monitoring facilities.
+ *
+ * @return the collection of threads
+ */
+ public final Collection<Thread> getQueuedThreads() {
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node p = tail; p != null; p = p.prev) {
+ Thread t = p.thread;
+ if (t != null)
+ list.add(t);
+ }
+ return list;
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire in exclusive mode. This has the same properties
+ * as {@link #getQueuedThreads} except that it only returns
+ * those threads waiting due to an exclusive acquire.
+ *
+ * @return the collection of threads
+ */
+ public final Collection<Thread> getExclusiveQueuedThreads() {
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node p = tail; p != null; p = p.prev) {
+ if (!p.isShared()) {
+ Thread t = p.thread;
+ if (t != null)
+ list.add(t);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire in shared mode. This has the same properties
+ * as {@link #getQueuedThreads} except that it only returns
+ * those threads waiting due to a shared acquire.
+ *
+ * @return the collection of threads
+ */
+ public final Collection<Thread> getSharedQueuedThreads() {
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node p = tail; p != null; p = p.prev) {
+ if (p.isShared()) {
+ Thread t = p.thread;
+ if (t != null)
+ list.add(t);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Returns a string identifying this synchronizer, as well as its state.
+ * The state, in brackets, includes the String {@code "State ="}
+ * followed by the current value of {@link #getState}, and either
+ * {@code "nonempty"} or {@code "empty"} depending on whether the
+ * queue is empty.
+ *
+ * @return a string identifying this synchronizer, as well as its state
+ */
+ public String toString() {
+ long s = getState();
+ String q = hasQueuedThreads()? "non" : "";
+ return super.toString() +
+ "[State = " + s + ", " + q + "empty queue]";
+ }
+
+
+ // Internal support methods for Conditions
+
+ /**
+ * Returns true if a node, always one that was initially placed on
+ * a condition queue, is now waiting to reacquire on sync queue.
+ * @param node the node
+ * @return true if is reacquiring
+ */
+ final boolean isOnSyncQueue(Node node) {
+ if (node.waitStatus == Node.CONDITION || node.prev == null)
+ return false;
+ if (node.next != null) // If has successor, it must be on queue
+ return true;
+ /*
+ * node.prev can be non-null, but not yet on queue because
+ * the CAS to place it on queue can fail. So we have to
+ * traverse from tail to make sure it actually made it. It
+ * will always be near the tail in calls to this method, and
+ * unless the CAS failed (which is unlikely), it will be
+ * there, so we hardly ever traverse much.
+ */
+ return findNodeFromTail(node);
+ }
+
+ /**
+ * Returns true if node is on sync queue by searching backwards from tail.
+ * Called only when needed by isOnSyncQueue.
+ * @return true if present
+ */
+ private boolean findNodeFromTail(Node node) {
+ Node t = tail;
+ for (;;) {
+ if (t == node)
+ return true;
+ if (t == null)
+ return false;
+ t = t.prev;
+ }
+ }
+
+ /**
+ * Transfers a node from a condition queue onto sync queue.
+ * Returns true if successful.
+ * @param node the node
+ * @return true if successfully transferred (else the node was
+ * cancelled before signal).
+ */
+ final boolean transferForSignal(Node node) {
+ /*
+ * If cannot change waitStatus, the node has been cancelled.
+ */
+ if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
+ return false;
+
+ /*
+ * 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).
+ */
+ Node p = enq(node);
+ int c = p.waitStatus;
+ if (c > 0 || !compareAndSetWaitStatus(p, c, Node.SIGNAL))
+ LockSupport.unpark(node.thread);
+ return true;
+ }
+
+ /**
+ * Transfers node, if necessary, to sync queue after a cancelled
+ * wait. Returns true if thread was cancelled before being
+ * signalled.
+ * @param current the waiting thread
+ * @param node its node
+ * @return true if cancelled before the node was signalled.
+ */
+ final boolean transferAfterCancelledWait(Node node) {
+ if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
+ enq(node);
+ return true;
+ }
+ /*
+ * If we lost out to a signal(), then we can't proceed
+ * until it finishes its enq(). Cancelling during an
+ * incomplete transfer is both rare and transient, so just
+ * spin.
+ */
+ while (!isOnSyncQueue(node))
+ Thread.yield();
+ return false;
+ }
+
+ /**
+ * Invokes release with current state value; returns saved state.
+ * Cancels node and throws exception on failure.
+ * @param node the condition node for this wait
+ * @return previous sync state
+ */
+ final long fullyRelease(Node node) {
+ try {
+ long savedState = getState();
+ if (release(savedState))
+ return savedState;
+ } catch (RuntimeException ex) {
+ node.waitStatus = Node.CANCELLED;
+ throw ex;
+ }
+ // reach here if release fails
+ node.waitStatus = Node.CANCELLED;
+ throw new IllegalMonitorStateException();
+ }
+
+ // Instrumentation methods for conditions
+
+ /**
+ * Queries whether the given ConditionObject
+ * uses this synchronizer as its lock.
+ *
+ * @param condition the condition
+ * @return <tt>true</tt> if owned
+ * @throws NullPointerException if the condition is null
+ */
+ public final boolean owns(ConditionObject condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ return condition.isOwnedBy(this);
+ }
+
+ /**
+ * Queries whether any threads are waiting on the given condition
+ * associated with this synchronizer. Note that because timeouts
+ * and interrupts may occur at any time, a <tt>true</tt> return
+ * does not guarantee that a future <tt>signal</tt> will awaken
+ * any threads. This method is designed primarily for use in
+ * monitoring of the system state.
+ *
+ * @param condition the condition
+ * @return <tt>true</tt> if there are any waiting threads
+ * @throws IllegalMonitorStateException if exclusive synchronization
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this synchronizer
+ * @throws NullPointerException if the condition is null
+ */
+ public final boolean hasWaiters(ConditionObject condition) {
+ if (!owns(condition))
+ throw new IllegalArgumentException("Not owner");
+ return condition.hasWaiters();
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting on the
+ * given condition associated with this synchronizer. Note that
+ * because timeouts and interrupts may occur at any time, the
+ * estimate serves only as an upper bound on the actual number of
+ * waiters. This method is designed for use in monitoring of the
+ * system state, not for synchronization control.
+ *
+ * @param condition the condition
+ * @return the estimated number of waiting threads
+ * @throws IllegalMonitorStateException if exclusive synchronization
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this synchronizer
+ * @throws NullPointerException if the condition is null
+ */
+ public final int getWaitQueueLength(ConditionObject condition) {
+ if (!owns(condition))
+ throw new IllegalArgumentException("Not owner");
+ return condition.getWaitQueueLength();
+ }
+
+ /**
+ * Returns a collection containing those threads that may be
+ * waiting on the given condition associated with this
+ * synchronizer. Because the actual set of threads may change
+ * dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order.
+ *
+ * @param condition the condition
+ * @return the collection of threads
+ * @throws IllegalMonitorStateException if exclusive synchronization
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this synchronizer
+ * @throws NullPointerException if the condition is null
+ */
+ public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
+ if (!owns(condition))
+ throw new IllegalArgumentException("Not owner");
+ return condition.getWaitingThreads();
+ }
+
+ /**
+ * Condition implementation for a {@link
+ * AbstractQueuedLongSynchronizer} serving as the basis of a {@link
+ * Lock} implementation.
+ *
+ * <p>Method documentation for this class describes mechanics,
+ * not behavioral specifications from the point of view of Lock
+ * and Condition users. Exported versions of this class will in
+ * general need to be accompanied by documentation describing
+ * condition semantics that rely on those of the associated
+ * <tt>AbstractQueuedLongSynchronizer</tt>.
+ *
+ * <p>This class is Serializable, but all fields are transient,
+ * so deserialized conditions have no waiters.
+ *
+ * @since 1.6
+ */
+ public class ConditionObject implements Condition, java.io.Serializable {
+ private static final long serialVersionUID = 1173984872572414699L;
+ /** First node of condition queue. */
+ private transient Node firstWaiter;
+ /** Last node of condition queue. */
+ private transient Node lastWaiter;
+
+ /**
+ * Creates a new <tt>ConditionObject</tt> instance.
+ */
+ public ConditionObject() { }
+
+ // Internal methods
+
+ /**
+ * Adds a new waiter to wait queue.
+ * @return its new wait node
+ */
+ private Node addConditionWaiter() {
+ Node node = new Node(Thread.currentThread(), Node.CONDITION);
+ Node t = lastWaiter;
+ if (t == null)
+ firstWaiter = node;
+ else
+ t.nextWaiter = node;
+ lastWaiter = node;
+ return node;
+ }
+
+ /**
+ * Removes and transfers nodes until hit non-cancelled one or
+ * null. Split out from signal in part to encourage compilers
+ * to inline the case of no waiters.
+ * @param first (non-null) the first node on condition queue
+ */
+ private void doSignal(Node first) {
+ do {
+ if ( (firstWaiter = first.nextWaiter) == null)
+ lastWaiter = null;
+ first.nextWaiter = null;
+ } while (!transferForSignal(first) &&
+ (first = firstWaiter) != null);
+ }
+
+ /**
+ * Removes and transfers all nodes.
+ * @param first (non-null) the first node on condition queue
+ */
+ private void doSignalAll(Node first) {
+ lastWaiter = firstWaiter = null;
+ do {
+ Node next = first.nextWaiter;
+ first.nextWaiter = null;
+ transferForSignal(first);
+ first = next;
+ } while (first != null);
+ }
+
+ /**
+ * Returns true if given node is on this condition queue.
+ * Call only when holding lock.
+ */
+ private boolean isOnConditionQueue(Node node) {
+ return node.next != null || node == lastWaiter;
+ }
+
+ /**
+ * Unlinks a cancelled waiter node from condition queue. This
+ * is called when cancellation occurred during condition wait,
+ * not lock wait, and is called only after lock has been
+ * re-acquired by a cancelled waiter and the node is not known
+ * to already have been dequeued. It is needed to avoid
+ * garbage retention in the absence of signals. So even though
+ * it may require a full traversal, it comes into play only
+ * when timeouts or cancellations occur in the absence of
+ * signals.
+ */
+ private void unlinkCancelledWaiter(Node node) {
+ Node t = firstWaiter;
+ Node trail = null;
+ while (t != null) {
+ if (t == node) {
+ Node next = t.nextWaiter;
+ if (trail == null)
+ firstWaiter = next;
+ else
+ trail.nextWaiter = next;
+ if (lastWaiter == node)
+ lastWaiter = trail;
+ break;
+ }
+ trail = t;
+ t = t.nextWaiter;
+ }
+ }
+
+ // public methods
+
+ /**
+ * Moves the longest-waiting thread, if one exists, from the
+ * wait queue for this condition to the wait queue for the
+ * owning lock.
+ *
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns {@code false}
+ */
+ public final void signal() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ Node first = firstWaiter;
+ if (first != null)
+ doSignal(first);
+ }
+
+ /**
+ * Moves all threads from the wait queue for this condition to
+ * the wait queue for the owning lock.
+ *
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns {@code false}
+ */
+ public final void signalAll() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ Node first = firstWaiter;
+ if (first != null)
+ doSignalAll(first);
+ }
+
+ /**
+ * Implements uninterruptible condition wait.
+ * <ol>
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * </ol>
+ */
+ public final void awaitUninterruptibly() {
+ Node node = addConditionWaiter();
+ long savedState = fullyRelease(node);
+ boolean interrupted = false;
+ while (!isOnSyncQueue(node)) {
+ LockSupport.park(this);
+ if (Thread.interrupted())
+ interrupted = true;
+ }
+ if (acquireQueued(node, savedState) || interrupted)
+ selfInterrupt();
+ }
+
+ /*
+ * For interruptible waits, we need to track whether to throw
+ * InterruptedException, if interrupted while blocked on
+ * condition, versus reinterrupt current thread, if
+ * interrupted while blocked waiting to re-acquire.
+ */
+
+ /** Mode meaning to reinterrupt on exit from wait */
+ private static final int REINTERRUPT = 1;
+ /** Mode meaning to throw InterruptedException on exit from wait */
+ private static final int THROW_IE = -1;
+
+ /**
+ * Checks for interrupt, returning THROW_IE if interrupted
+ * before signalled, REINTERRUPT if after signalled, or
+ * 0 if not interrupted.
+ */
+ private int checkInterruptWhileWaiting(Node node) {
+ return (Thread.interrupted()) ?
+ ((transferAfterCancelledWait(node))? THROW_IE : REINTERRUPT) :
+ 0;
+ }
+
+ /**
+ * Throws InterruptedException, reinterrupts current thread, or
+ * does nothing, depending on mode.
+ */
+ private void reportInterruptAfterWait(int interruptMode)
+ throws InterruptedException {
+ if (interruptMode == THROW_IE)
+ throw new InterruptedException();
+ else if (interruptMode == REINTERRUPT)
+ selfInterrupt();
+ }
+
+ /**
+ * Implements interruptible condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled or interrupted
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw exception
+ * </ol>
+ */
+ public final void await() throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ long savedState = fullyRelease(node);
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ LockSupport.park(this);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (isOnConditionQueue(node))
+ unlinkCancelledWaiter(node);
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ }
+
+ /**
+ * Implements timed condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled, interrupted, or timed out
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw InterruptedException
+ * </ol>
+ */
+ public final long awaitNanos(long nanosTimeout) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ long savedState = fullyRelease(node);
+ long lastTime = System.nanoTime();
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ if (nanosTimeout <= 0L) {
+ transferAfterCancelledWait(node);
+ break;
+ }
+ LockSupport.parkNanos(this, nanosTimeout);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (isOnConditionQueue(node))
+ unlinkCancelledWaiter(node);
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ return nanosTimeout - (System.nanoTime() - lastTime);
+ }
+
+ /**
+ * Implements absolute timed condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled, interrupted, or timed out
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw InterruptedException
+ * <li> If timed out while blocked in step 4, return false, else true
+ * </ol>
+ */
+ public final boolean awaitUntil(Date deadline) throws InterruptedException {
+ if (deadline == null)
+ throw new NullPointerException();
+ long abstime = deadline.getTime();
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ long savedState = fullyRelease(node);
+ boolean timedout = false;
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ if (System.currentTimeMillis() > abstime) {
+ timedout = transferAfterCancelledWait(node);
+ break;
+ }
+ LockSupport.parkUntil(this, abstime);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (isOnConditionQueue(node))
+ unlinkCancelledWaiter(node);
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ return !timedout;
+ }
+
+ /**
+ * Implements timed condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled, interrupted, or timed out
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw InterruptedException
+ * <li> If timed out while blocked in step 4, return false, else true
+ * </ol>
+ */
+ public final boolean await(long time, TimeUnit unit) throws InterruptedException {
+ if (unit == null)
+ throw new NullPointerException();
+ long nanosTimeout = unit.toNanos(time);
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ long savedState = fullyRelease(node);
+ long lastTime = System.nanoTime();
+ boolean timedout = false;
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ if (nanosTimeout <= 0L) {
+ timedout = transferAfterCancelledWait(node);
+ break;
+ }
+ LockSupport.parkNanos(this, nanosTimeout);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (isOnConditionQueue(node))
+ unlinkCancelledWaiter(node);
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ return !timedout;
+ }
+
+ // support for instrumentation
+
+ /**
+ * Returns true if this condition was created by the given
+ * synchronization object.
+ *
+ * @return {@code true} if owned
+ */
+ final boolean isOwnedBy(AbstractQueuedLongSynchronizer sync) {
+ return sync == AbstractQueuedLongSynchronizer.this;
+ }
+
+ /**
+ * Queries whether any threads are waiting on this condition.
+ * Implements {@link AbstractQueuedLongSynchronizer#hasWaiters}.
+ *
+ * @return {@code true} if there are any waiting threads
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns {@code false}
+ */
+ protected final boolean hasWaiters() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+ if (w.waitStatus == Node.CONDITION)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting on
+ * this condition.
+ * Implements {@link AbstractQueuedLongSynchronizer#getWaitQueueLength}.
+ *
+ * @return the estimated number of waiting threads
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns {@code false}
+ */
+ protected final int getWaitQueueLength() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ int n = 0;
+ for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+ if (w.waitStatus == Node.CONDITION)
+ ++n;
+ }
+ return n;
+ }
+
+ /**
+ * Returns a collection containing those threads that may be
+ * waiting on this Condition.
+ * Implements {@link AbstractQueuedLongSynchronizer#getWaitingThreads}.
+ *
+ * @return the collection of threads
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns {@code false}
+ */
+ protected final Collection<Thread> getWaitingThreads() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+ if (w.waitStatus == Node.CONDITION) {
+ Thread t = w.thread;
+ if (t != null)
+ list.add(t);
+ }
+ }
+ return list;
+ }
+ }
+
+ /**
+ * Setup to support compareAndSet. We need to natively implement
+ * this here: For the sake of permitting future enhancements, we
+ * cannot explicitly subclass AtomicLong, which would be
+ * efficient and useful otherwise. So, as the lesser of evils, we
+ * natively implement using hotspot intrinsics API. And while we
+ * are at it, we do the same for other CASable fields (which could
+ * otherwise be done with atomic field updaters).
+ */
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final long stateOffset;
+ private static final long headOffset;
+ private static final long tailOffset;
+ private static final long waitStatusOffset;
+
+ static {
+ try {
+ stateOffset = unsafe.objectFieldOffset
+ (AbstractQueuedLongSynchronizer.class.getDeclaredField("state"));
+ headOffset = unsafe.objectFieldOffset
+ (AbstractQueuedLongSynchronizer.class.getDeclaredField("head"));
+ tailOffset = unsafe.objectFieldOffset
+ (AbstractQueuedLongSynchronizer.class.getDeclaredField("tail"));
+ waitStatusOffset = unsafe.objectFieldOffset
+ (Node.class.getDeclaredField("waitStatus"));
+
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
+ /**
+ * CAS head field. Used only by enq
+ */
+ private final boolean compareAndSetHead(Node update) {
+ return unsafe.compareAndSwapObject(this, headOffset, null, update);
+ }
+
+ /**
+ * CAS tail field. Used only by enq
+ */
+ private final boolean compareAndSetTail(Node expect, Node update) {
+ return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
+ }
+
+ /**
+ * CAS waitStatus field of a node.
+ */
+ private final static boolean compareAndSetWaitStatus(Node node,
+ int expect,
+ int update) {
+ return unsafe.compareAndSwapInt(node, waitStatusOffset,
+ expect, update);
+ }
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
new file mode 100644
index 000000000..647f4fcbc
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
@@ -0,0 +1,2159 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import sun.misc.Unsafe;
+
+/**
+ * Provides a framework for implementing blocking locks and related
+ * synchronizers (semaphores, events, etc) that rely on
+ * first-in-first-out (FIFO) wait queues. This class is designed to
+ * be a useful basis for most kinds of synchronizers that rely on a
+ * single atomic <tt>int</tt> value to represent state. Subclasses
+ * must define the protected methods that change this state, and which
+ * define what that state means in terms of this object being acquired
+ * or released. Given these, the other methods in this class carry
+ * out all queuing and blocking mechanics. Subclasses can maintain
+ * other state fields, but only the atomically updated <tt>int</tt>
+ * value manipulated using methods {@link #getState}, {@link
+ * #setState} and {@link #compareAndSetState} is tracked with respect
+ * to synchronization.
+ *
+ * <p>Subclasses should be defined as non-public internal helper
+ * classes that are used to implement the synchronization properties
+ * of their enclosing class. Class
+ * <tt>AbstractQueuedSynchronizer</tt> does not implement any
+ * synchronization interface. Instead it defines methods such as
+ * {@link #acquireInterruptibly} that can be invoked as
+ * appropriate by concrete locks and related synchronizers to
+ * implement their public methods.
+ *
+ * <p>This class supports either or both a default <em>exclusive</em>
+ * mode and a <em>shared</em> mode. When acquired in exclusive mode,
+ * attempted acquires by other threads cannot succeed. Shared mode
+ * acquires by multiple threads may (but need not) succeed. This class
+ * does not &quot;understand&quot; these differences except in the
+ * mechanical sense that when a shared mode acquire succeeds, the next
+ * waiting thread (if one exists) must also determine whether it can
+ * acquire as well. Threads waiting in the different modes share the
+ * same FIFO queue. Usually, implementation subclasses support only
+ * one of these modes, but both can come into play for example in a
+ * {@link ReadWriteLock}. Subclasses that support only exclusive or
+ * only shared modes need not define the methods supporting the unused mode.
+ *
+ * <p>This class defines a nested {@link ConditionObject} class that
+ * can be used as a {@link Condition} implementation by subclasses
+ * supporting exclusive mode for which method {@link
+ * #isHeldExclusively} reports whether synchronization is exclusively
+ * held with respect to the current thread, method {@link #release}
+ * invoked with the current {@link #getState} value fully releases
+ * this object, and {@link #acquire}, given this saved state value,
+ * eventually restores this object to its previous acquired state. No
+ * <tt>AbstractQueuedSynchronizer</tt> method otherwise creates such a
+ * condition, so if this constraint cannot be met, do not use it. The
+ * behavior of {@link ConditionObject} depends of course on the
+ * semantics of its synchronizer implementation.
+ *
+ * <p>This class provides inspection, instrumentation, and monitoring
+ * methods for the internal queue, as well as similar methods for
+ * condition objects. These can be exported as desired into classes
+ * using an <tt>AbstractQueuedSynchronizer</tt> for their
+ * synchronization mechanics.
+ *
+ * <p>Serialization of this class stores only the underlying atomic
+ * integer maintaining state, so deserialized objects have empty
+ * thread queues. Typical subclasses requiring serializability will
+ * define a <tt>readObject</tt> method that restores this to a known
+ * initial state upon deserialization.
+ *
+ * <h3>Usage</h3>
+ *
+ * <p>To use this class as the basis of a synchronizer, redefine the
+ * following methods, as applicable, by inspecting and/or modifying
+ * the synchronization state using {@link #getState}, {@link
+ * #setState} and/or {@link #compareAndSetState}:
+ *
+ * <ul>
+ * <li> {@link #tryAcquire}
+ * <li> {@link #tryRelease}
+ * <li> {@link #tryAcquireShared}
+ * <li> {@link #tryReleaseShared}
+ * <li> {@link #isHeldExclusively}
+ *</ul>
+ *
+ * Each of these methods by default throws {@link
+ * UnsupportedOperationException}. Implementations of these methods
+ * must be internally thread-safe, and should in general be short and
+ * not block. Defining these methods is the <em>only</em> supported
+ * means of using this class. All other methods are declared
+ * <tt>final</tt> because they cannot be independently varied.
+ *
+ * <p>You may also find the inherited methods from {@link
+ * AbstractOwnableSynchronizer} useful to keep track of the thread
+ * owning an exclusive synchronizer. You are encouraged to use them
+ * -- this enables monitoring and diagnostic tools to assist users in
+ * determining which threads hold locks.
+ *
+ * <p>Even though this class is based on an internal FIFO queue, it
+ * does not automatically enforce FIFO acquisition policies. The core
+ * of exclusive synchronization takes the form:
+ *
+ * <pre>
+ * Acquire:
+ * while (!tryAcquire(arg)) {
+ * <em>enqueue thread if it is not already queued</em>;
+ * <em>possibly block current thread</em>;
+ * }
+ *
+ * Release:
+ * if (tryRelease(arg))
+ * <em>unblock the first queued thread</em>;
+ * </pre>
+ *
+ * (Shared mode is similar but may involve cascading signals.)
+ *
+ * <p>Because checks in acquire are invoked before enqueuing, a newly
+ * acquiring thread may <em>barge</em> ahead of others that are
+ * blocked and queued. However, you can, if desired, define
+ * <tt>tryAcquire</tt> and/or <tt>tryAcquireShared</tt> to disable
+ * barging by internally invoking one or more of the inspection
+ * methods. In particular, a strict FIFO lock can define
+ * <tt>tryAcquire</tt> to immediately return <tt>false</tt> if {@link
+ * #getFirstQueuedThread} does not return the current thread. A
+ * normally preferable non-strict fair version can immediately return
+ * <tt>false</tt> only if {@link #hasQueuedThreads} returns
+ * <tt>true</tt> and <tt>getFirstQueuedThread</tt> is not the current
+ * thread; or equivalently, that <tt>getFirstQueuedThread</tt> is both
+ * non-null and not the current thread. Further variations are
+ * possible.
+ *
+ * <p>Throughput and scalability are generally highest for the
+ * default barging (also known as <em>greedy</em>,
+ * <em>renouncement</em>, and <em>convoy-avoidance</em>) strategy.
+ * While this is not guaranteed to be fair or starvation-free, earlier
+ * queued threads are allowed to recontend before later queued
+ * threads, and each recontention has an unbiased chance to succeed
+ * against incoming threads. Also, while acquires do not
+ * &quot;spin&quot; in the usual sense, they may perform multiple
+ * invocations of <tt>tryAcquire</tt> interspersed with other
+ * computations before blocking. This gives most of the benefits of
+ * spins when exclusive synchronization is only briefly held, without
+ * most of the liabilities when it isn't. If so desired, you can
+ * augment this by preceding calls to acquire methods with
+ * "fast-path" checks, possibly prechecking {@link #hasContended}
+ * and/or {@link #hasQueuedThreads} to only do so if the synchronizer
+ * is likely not to be contended.
+ *
+ * <p>This class provides an efficient and scalable basis for
+ * synchronization in part by specializing its range of use to
+ * synchronizers that can rely on <tt>int</tt> state, acquire, and
+ * release parameters, and an internal FIFO wait queue. When this does
+ * not suffice, you can build synchronizers from a lower level using
+ * {@link java.util.concurrent.atomic atomic} classes, your own custom
+ * {@link java.util.Queue} classes, and {@link LockSupport} blocking
+ * support.
+ *
+ * <h3>Usage Examples</h3>
+ *
+ * <p>Here is a non-reentrant mutual exclusion lock class that uses
+ * the value zero to represent the unlocked state, and one to
+ * represent the locked state. While a non-reentrant lock
+ * does not strictly require recording of the current owner
+ * thread, this class does so anyway to make usage easier to monitor.
+ * It also supports conditions and exposes
+ * one of the instrumentation methods:
+ *
+ * <pre>
+ * class Mutex implements Lock, java.io.Serializable {
+ *
+ * // Our internal helper class
+ * private static class Sync extends AbstractQueuedSynchronizer {
+ * // Report whether in locked state
+ * protected boolean isHeldExclusively() {
+ * return getState() == 1;
+ * }
+ *
+ * // Acquire the lock if state is zero
+ * public boolean tryAcquire(int acquires) {
+ * assert acquires == 1; // Otherwise unused
+ * if (compareAndSetState(0, 1)) {
+ * setExclusiveOwnerThread(Thread.currentThread());
+ * return true;
+ * }
+ * return false;
+ * }
+ *
+ * // Release the lock by setting state to zero
+ * protected boolean tryRelease(int releases) {
+ * assert releases == 1; // Otherwise unused
+ * if (getState() == 0) throw new IllegalMonitorStateException();
+ * setExclusiveOwnerThread(null);
+ * setState(0);
+ * return true;
+ * }
+ *
+ * // Provide a Condition
+ * Condition newCondition() { return new ConditionObject(); }
+ *
+ * // Deserialize properly
+ * private void readObject(ObjectInputStream s)
+ * throws IOException, ClassNotFoundException {
+ * s.defaultReadObject();
+ * setState(0); // reset to unlocked state
+ * }
+ * }
+ *
+ * // The sync object does all the hard work. We just forward to it.
+ * private final Sync sync = new Sync();
+ *
+ * public void lock() { sync.acquire(1); }
+ * public boolean tryLock() { return sync.tryAcquire(1); }
+ * public void unlock() { sync.release(1); }
+ * public Condition newCondition() { return sync.newCondition(); }
+ * public boolean isLocked() { return sync.isHeldExclusively(); }
+ * public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
+ * public void lockInterruptibly() throws InterruptedException {
+ * sync.acquireInterruptibly(1);
+ * }
+ * public boolean tryLock(long timeout, TimeUnit unit)
+ * throws InterruptedException {
+ * return sync.tryAcquireNanos(1, unit.toNanos(timeout));
+ * }
+ * }
+ * </pre>
+ *
+ * <p>Here is a latch class that is like a {@link CountDownLatch}
+ * except that it only requires a single <tt>signal</tt> to
+ * fire. Because a latch is non-exclusive, it uses the <tt>shared</tt>
+ * acquire and release methods.
+ *
+ * <pre>
+ * class BooleanLatch {
+ *
+ * private static class Sync extends AbstractQueuedSynchronizer {
+ * boolean isSignalled() { return getState() != 0; }
+ *
+ * protected int tryAcquireShared(int ignore) {
+ * return isSignalled()? 1 : -1;
+ * }
+ *
+ * protected boolean tryReleaseShared(int ignore) {
+ * setState(1);
+ * return true;
+ * }
+ * }
+ *
+ * private final Sync sync = new Sync();
+ * public boolean isSignalled() { return sync.isSignalled(); }
+ * public void signal() { sync.releaseShared(1); }
+ * public void await() throws InterruptedException {
+ * sync.acquireSharedInterruptibly(1);
+ * }
+ * }
+ * </pre>
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public abstract class AbstractQueuedSynchronizer
+ extends AbstractOwnableSynchronizer
+ implements java.io.Serializable {
+
+ private static final long serialVersionUID = 7373984972572414691L;
+
+ /**
+ * Creates a new <tt>AbstractQueuedSynchronizer</tt> instance
+ * with initial synchronization state of zero.
+ */
+ protected AbstractQueuedSynchronizer() { }
+
+ /**
+ * Wait queue node class.
+ *
+ * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and
+ * Hagersten) lock queue. CLH locks are normally used for
+ * spinlocks. We instead use them for blocking synchronizers, but
+ * use the same basic tactic of holding some of the control
+ * information about a thread in the predecessor of its node. A
+ * "status" field in each node keeps track of whether a thread
+ * should block. A node is signalled when its predecessor
+ * releases. Each node of the queue otherwise serves as a
+ * specific-notification-style monitor holding a single waiting
+ * thread. The status field does NOT control whether threads are
+ * granted locks etc though. A thread may try to acquire if it is
+ * first in the queue. But being first does not guarantee success;
+ * it only gives the right to contend. So the currently released
+ * contender thread may need to rewait.
+ *
+ * <p>To enqueue into a CLH lock, you atomically splice it in as new
+ * tail. To dequeue, you just set the head field.
+ * <pre>
+ * +------+ prev +-----+ +-----+
+ * head | | <---- | | <---- | | tail
+ * +------+ +-----+ +-----+
+ * </pre>
+ *
+ * <p>Insertion into a CLH queue requires only a single atomic
+ * operation on "tail", so there is a simple atomic point of
+ * demarcation from unqueued to queued. Similarly, dequeing
+ * involves only updating the "head". However, it takes a bit
+ * more work for nodes to determine who their successors are,
+ * in part to deal with possible cancellation due to timeouts
+ * and interrupts.
+ *
+ * <p>The "prev" links (not used in original CLH locks), are mainly
+ * needed to handle cancellation. If a node is cancelled, its
+ * successor is (normally) relinked to a non-cancelled
+ * predecessor. For explanation of similar mechanics in the case
+ * of spin locks, see the papers by Scott and Scherer at
+ * http://www.cs.rochester.edu/u/scott/synchronization/
+ *
+ * <p>We also use "next" links to implement blocking mechanics.
+ * The thread id for each node is kept in its own node, so a
+ * predecessor signals the next node to wake up by traversing
+ * next link to determine which thread it is. Determination of
+ * successor must avoid races with newly queued nodes to set
+ * the "next" fields of their predecessors. This is solved
+ * when necessary by checking backwards from the atomically
+ * updated "tail" when a node's successor appears to be null.
+ * (Or, said differently, the next-links are an optimization
+ * so that we don't usually need a backward scan.)
+ *
+ * <p>Cancellation introduces some conservatism to the basic
+ * algorithms. Since we must poll for cancellation of other
+ * nodes, we can miss noticing whether a cancelled node is
+ * ahead or behind us. This is dealt with by always unparking
+ * successors upon cancellation, allowing them to stabilize on
+ * a new predecessor.
+ *
+ * <p>CLH queues need a dummy header node to get started. But
+ * we don't create them on construction, because it would be wasted
+ * effort if there is never contention. Instead, the node
+ * is constructed and head and tail pointers are set upon first
+ * contention.
+ *
+ * <p>Threads waiting on Conditions use the same nodes, but
+ * use an additional link. Conditions only need to link nodes
+ * in simple (non-concurrent) linked queues because they are
+ * only accessed when exclusively held. Upon await, a node is
+ * inserted into a condition queue. Upon signal, the node is
+ * transferred to the main queue. A special value of status
+ * field is used to mark which queue a node is on.
+ *
+ * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill
+ * Scherer and Michael Scott, along with members of JSR-166
+ * expert group, for helpful ideas, discussions, and critiques
+ * on the design of this class.
+ */
+ static final class Node {
+ /** waitStatus value to indicate thread has cancelled */
+ static final int CANCELLED = 1;
+ /** waitStatus value to indicate successor's thread needs unparking */
+ static final int SIGNAL = -1;
+ /** waitStatus value to indicate thread is waiting on condition */
+ static final int CONDITION = -2;
+ /** Marker to indicate a node is waiting in shared mode */
+ static final Node SHARED = new Node();
+ /** Marker to indicate a node is waiting in exclusive mode */
+ static final Node EXCLUSIVE = null;
+
+ /**
+ * Status field, taking on only the values:
+ * SIGNAL: The successor of this node is (or will soon be)
+ * blocked (via park), so the current node must
+ * unpark its successor when it releases or
+ * cancels. To avoid races, acquire methods must
+ * first indicate they need a signal,
+ * then retry the atomic acquire, and then,
+ * on failure, block.
+ * CANCELLED: This node is cancelled due to timeout or interrupt.
+ * Nodes never leave this state. In particular,
+ * a thread with cancelled node never again blocks.
+ * CONDITION: This node is currently on a condition queue.
+ * It will not be used as a sync queue node until
+ * transferred. (Use of this value here
+ * has nothing to do with the other uses
+ * of the field, but simplifies mechanics.)
+ * 0: None of the above
+ *
+ * The values are arranged numerically to simplify use.
+ * Non-negative values mean that a node doesn't need to
+ * signal. So, most code doesn't need to check for particular
+ * values, just for sign.
+ *
+ * The field is initialized to 0 for normal sync nodes, and
+ * CONDITION for condition nodes. It is modified only using
+ * CAS.
+ */
+ volatile int waitStatus;
+
+ /**
+ * Link to predecessor node that current node/thread relies on
+ * for checking waitStatus. Assigned during enqueing, and nulled
+ * out (for sake of GC) only upon dequeuing. Also, upon
+ * cancellation of a predecessor, we short-circuit while
+ * finding a non-cancelled one, which will always exist
+ * because the head node is never cancelled: A node becomes
+ * head only as a result of successful acquire. A
+ * cancelled thread never succeeds in acquiring, and a thread only
+ * cancels itself, not any other node.
+ */
+ volatile Node prev;
+
+ /**
+ * Link to the successor node that the current node/thread
+ * unparks upon release. Assigned once during enqueuing, and
+ * nulled out (for sake of GC) when no longer needed. Upon
+ * cancellation, we cannot adjust this field, but can notice
+ * status and bypass the node if cancelled. The enq operation
+ * does not assign next field of a predecessor until after
+ * attachment, so seeing a null next field does not
+ * necessarily mean that node is at end of queue. However, if
+ * a next field appears to be null, we can scan prev's from
+ * the tail to double-check.
+ */
+ volatile Node next;
+
+ /**
+ * The thread that enqueued this node. Initialized on
+ * construction and nulled out after use.
+ */
+ volatile Thread thread;
+
+ /**
+ * Link to next node waiting on condition, or the special
+ * value SHARED. Because condition queues are accessed only
+ * when holding in exclusive mode, we just need a simple
+ * linked queue to hold nodes while they are waiting on
+ * conditions. They are then transferred to the queue to
+ * re-acquire. And because conditions can only be exclusive,
+ * we save a field by using special value to indicate shared
+ * mode.
+ */
+ Node nextWaiter;
+
+ /**
+ * Returns true if node is waiting in shared mode
+ */
+ final boolean isShared() {
+ return nextWaiter == SHARED;
+ }
+
+ /**
+ * Returns previous node, or throws NullPointerException if
+ * null. Use when predecessor cannot be null.
+ * @return the predecessor of this node
+ */
+ final Node predecessor() throws NullPointerException {
+ Node p = prev;
+ if (p == null)
+ throw new NullPointerException();
+ else
+ return p;
+ }
+
+ Node() { // Used to establish initial head or SHARED marker
+ }
+
+ Node(Thread thread, Node mode) { // Used by addWaiter
+ this.nextWaiter = mode;
+ this.thread = thread;
+ }
+
+ Node(Thread thread, int waitStatus) { // Used by Condition
+ this.waitStatus = waitStatus;
+ this.thread = thread;
+ }
+ }
+
+ /**
+ * Head of the wait queue, lazily initialized. Except for
+ * initialization, it is modified only via method setHead. Note:
+ * If head exists, its waitStatus is guaranteed not to be
+ * CANCELLED.
+ */
+ private transient volatile Node head;
+
+ /**
+ * Tail of the wait queue, lazily initialized. Modified only via
+ * method enq to add new wait node.
+ */
+ private transient volatile Node tail;
+
+ /**
+ * The synchronization state.
+ */
+ private volatile int state;
+
+ /**
+ * Returns the current value of synchronization state.
+ * This operation has memory semantics of a <tt>volatile</tt> read.
+ * @return current state value
+ */
+ protected final int getState() {
+ return state;
+ }
+
+ /**
+ * Sets the value of synchronization state.
+ * This operation has memory semantics of a <tt>volatile</tt> write.
+ * @param newState the new state value
+ */
+ protected final void setState(int newState) {
+ state = newState;
+ }
+
+ /**
+ * Atomically sets synchronization state to the given updated
+ * value if the current state value equals the expected value.
+ * This operation has memory semantics of a <tt>volatile</tt> read
+ * and write.
+ *
+ * @param expect the expected value
+ * @param update the new value
+ * @return true if successful. False return indicates that the actual
+ * value was not equal to the expected value.
+ */
+ protected final boolean compareAndSetState(int expect, int update) {
+ // See below for intrinsics setup to support this
+ return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
+ }
+
+ // Queuing utilities
+
+ /**
+ * The number of nanoseconds for which it is faster to spin
+ * rather than to use timed park. A rough estimate suffices
+ * to improve responsiveness with very short timeouts.
+ */
+ static final long spinForTimeoutThreshold = 1000L;
+
+ /**
+ * Inserts node into queue, initializing if necessary. See picture above.
+ * @param node the node to insert
+ * @return node's predecessor
+ */
+ private Node enq(final Node node) {
+ for (;;) {
+ Node t = tail;
+ if (t == null) { // Must initialize
+ Node h = new Node(); // Dummy header
+ h.next = node;
+ node.prev = h;
+ if (compareAndSetHead(h)) {
+ tail = node;
+ return h;
+ }
+ }
+ else {
+ node.prev = t;
+ if (compareAndSetTail(t, node)) {
+ t.next = node;
+ return t;
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates and enqueues node for given thread and mode.
+ *
+ * @param current the thread
+ * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
+ * @return the new node
+ */
+ private Node addWaiter(Node mode) {
+ Node node = new Node(Thread.currentThread(), mode);
+ // Try the fast path of enq; backup to full enq on failure
+ Node pred = tail;
+ if (pred != null) {
+ node.prev = pred;
+ if (compareAndSetTail(pred, node)) {
+ pred.next = node;
+ return node;
+ }
+ }
+ enq(node);
+ return node;
+ }
+
+ /**
+ * Sets head of queue to be node, thus dequeuing. Called only by
+ * acquire methods. Also nulls out unused fields for sake of GC
+ * and to suppress unnecessary signals and traversals.
+ *
+ * @param node the node
+ */
+ private void setHead(Node node) {
+ head = node;
+ node.thread = null;
+ node.prev = null;
+ }
+
+ /**
+ * Wakes up node's successor, if one exists.
+ *
+ * @param node the node
+ */
+ private void unparkSuccessor(Node node) {
+ /*
+ * Try to clear status in anticipation of signalling. It is
+ * OK if this fails or if status is changed by waiting thread.
+ */
+ compareAndSetWaitStatus(node, Node.SIGNAL, 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.
+ */
+ Node s = node.next;
+ if (s == null || s.waitStatus > 0) {
+ s = null;
+ for (Node t = tail; t != null && t != node; t = t.prev)
+ if (t.waitStatus <= 0)
+ s = t;
+ }
+ if (s != null)
+ LockSupport.unpark(s.thread);
+ }
+
+ /**
+ * Sets head of queue, and checks if successor may be waiting
+ * in shared mode, if so propagating if propagate > 0.
+ *
+ * @param pred the node holding waitStatus for node
+ * @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);
+ }
+ }
+
+ // Utilities for various versions of acquire
+
+ /**
+ * Cancels an ongoing attempt to acquire.
+ *
+ * @param node the node
+ */
+ private void cancelAcquire(Node node) {
+ if (node != null) { // Ignore if node doesn't exist
+ node.thread = null;
+ // Can use unconditional write instead of CAS here
+ node.waitStatus = Node.CANCELLED;
+ unparkSuccessor(node);
+ }
+ }
+
+ /**
+ * Checks and updates status for a node that failed to acquire.
+ * Returns true if thread should block. This is the main signal
+ * control in all acquire loops. Requires that pred == node.prev
+ *
+ * @param pred node's predecessor holding status
+ * @param node the node
+ * @return {@code true} if thread should block
+ */
+ private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
+ int s = pred.waitStatus;
+ if (s < 0)
+ /*
+ * This node has already set status asking a release
+ * to signal it, so it can safely park
+ */
+ return true;
+ if (s > 0)
+ /*
+ * Predecessor was cancelled. Move up to its predecessor
+ * and indicate retry.
+ */
+ node.prev = pred.prev;
+ else
+ /*
+ * 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, 0, Node.SIGNAL);
+ return false;
+ }
+
+ /**
+ * Convenience method to interrupt current thread.
+ */
+ private static void selfInterrupt() {
+ Thread.currentThread().interrupt();
+ }
+
+ /**
+ * Convenience method to park and then check if interrupted
+ *
+ * @return {@code true} if interrupted
+ */
+ private final boolean parkAndCheckInterrupt() {
+ LockSupport.park(this);
+ return Thread.interrupted();
+ }
+
+ /*
+ * Various flavors of acquire, varying in exclusive/shared and
+ * control modes. Each is mostly the same, but annoyingly
+ * different. Only a little bit of factoring is possible due to
+ * interactions of exception mechanics (including ensuring that we
+ * cancel if tryAcquire throws exception) and other control, at
+ * least not without hurting performance too much.
+ */
+
+ /**
+ * 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) {
+ try {
+ boolean interrupted = false;
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head && tryAcquire(arg)) {
+ setHead(node);
+ p.next = null; // help GC
+ return interrupted;
+ }
+ if (shouldParkAfterFailedAcquire(p, node) &&
+ parkAndCheckInterrupt())
+ interrupted = true;
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ }
+
+ /**
+ * Acquires in exclusive interruptible mode.
+ * @param arg the acquire argument
+ */
+ private void doAcquireInterruptibly(int arg)
+ throws InterruptedException {
+ final Node node = addWaiter(Node.EXCLUSIVE);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head && tryAcquire(arg)) {
+ 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 timed mode.
+ *
+ * @param arg the acquire argument
+ * @param nanosTimeout max wait time
+ * @return {@code true} if acquired
+ */
+ private boolean doAcquireNanos(int arg, long nanosTimeout)
+ throws InterruptedException {
+ long lastTime = System.nanoTime();
+ final Node node = addWaiter(Node.EXCLUSIVE);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head && tryAcquire(arg)) {
+ setHead(node);
+ p.next = null; // help GC
+ return true;
+ }
+ if (nanosTimeout <= 0) {
+ cancelAcquire(node);
+ return false;
+ }
+ if (nanosTimeout > spinForTimeoutThreshold &&
+ shouldParkAfterFailedAcquire(p, node))
+ LockSupport.parkNanos(this, nanosTimeout);
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ if (Thread.interrupted())
+ break;
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ // Arrive here only if interrupted
+ cancelAcquire(node);
+ throw new InterruptedException();
+ }
+
+ /**
+ * Acquires in shared uninterruptible mode.
+ * @param arg the acquire argument
+ */
+ private void doAcquireShared(int arg) {
+ final Node node = addWaiter(Node.SHARED);
+ try {
+ boolean interrupted = false;
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head) {
+ int r = tryAcquireShared(arg);
+ 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;
+ }
+ }
+
+ /**
+ * Acquires in shared interruptible mode.
+ * @param arg the acquire argument
+ */
+ private void doAcquireSharedInterruptibly(int arg)
+ throws InterruptedException {
+ final Node node = addWaiter(Node.SHARED);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head) {
+ int r = tryAcquireShared(arg);
+ if (r >= 0) {
+ setHeadAndPropagate(node, r);
+ 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 shared timed mode.
+ *
+ * @param arg the acquire argument
+ * @param nanosTimeout max wait time
+ * @return {@code true} if acquired
+ */
+ private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
+ throws InterruptedException {
+
+ long lastTime = System.nanoTime();
+ final Node node = addWaiter(Node.SHARED);
+ try {
+ for (;;) {
+ final Node p = node.predecessor();
+ if (p == head) {
+ int r = tryAcquireShared(arg);
+ if (r >= 0) {
+ setHeadAndPropagate(node, r);
+ p.next = null; // help GC
+ return true;
+ }
+ }
+ if (nanosTimeout <= 0) {
+ cancelAcquire(node);
+ return false;
+ }
+ if (nanosTimeout > spinForTimeoutThreshold &&
+ shouldParkAfterFailedAcquire(p, node))
+ LockSupport.parkNanos(this, nanosTimeout);
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ if (Thread.interrupted())
+ break;
+ }
+ } catch (RuntimeException ex) {
+ cancelAcquire(node);
+ throw ex;
+ }
+ // Arrive here only if interrupted
+ cancelAcquire(node);
+ throw new InterruptedException();
+ }
+
+ // Main exported methods
+
+ /**
+ * Attempts to acquire in exclusive mode. This method should query
+ * if the state of the object permits it to be acquired in the
+ * exclusive mode, and if so to acquire it.
+ *
+ * <p>This method is always invoked by the thread performing
+ * acquire. If this method reports failure, the acquire method
+ * may queue the thread, if it is not already queued, until it is
+ * signalled by a release from some other thread. This can be used
+ * to implement method {@link Lock#tryLock()}.
+ *
+ * <p>The default
+ * implementation throws {@link UnsupportedOperationException}.
+ *
+ * @param arg the acquire argument. This value is always the one
+ * passed to an acquire method, or is the value saved on entry
+ * to a condition wait. The value is otherwise uninterpreted
+ * and can represent anything you like.
+ * @return {@code true} if successful. Upon success, this object has
+ * been acquired.
+ * @throws IllegalMonitorStateException if acquiring would place this
+ * synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if exclusive mode is not supported
+ */
+ protected boolean tryAcquire(int arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Attempts to set the state to reflect a release in exclusive
+ * mode.
+ *
+ * <p>This method is always invoked by the thread performing release.
+ *
+ * <p>The default implementation throws
+ * {@link UnsupportedOperationException}.
+ *
+ * @param arg the release argument. This value is always the one
+ * passed to a release method, or the current state value upon
+ * entry to a condition wait. The value is otherwise
+ * uninterpreted and can represent anything you like.
+ * @return {@code true} if this object is now in a fully released
+ * state, so that any waiting threads may attempt to acquire;
+ * and {@code false} otherwise.
+ * @throws IllegalMonitorStateException if releasing would place this
+ * synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if exclusive mode is not supported
+ */
+ protected boolean tryRelease(int arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Attempts to acquire in shared mode. This method should query if
+ * the state of the object permits it to be acquired in the shared
+ * mode, and if so to acquire it.
+ *
+ * <p>This method is always invoked by the thread performing
+ * acquire. If this method reports failure, the acquire method
+ * may queue the thread, if it is not already queued, until it is
+ * signalled by a release from some other thread.
+ *
+ * <p>The default implementation throws {@link
+ * UnsupportedOperationException}.
+ *
+ * @param arg the acquire argument. This value is always the one
+ * passed to an acquire method, or is the value saved on entry
+ * to a condition wait. The value is otherwise uninterpreted
+ * and can represent anything you like.
+ * @return a negative value on failure; zero if acquisition in shared
+ * mode succeeded but no subsequent shared-mode acquire can
+ * succeed; and a positive value if acquisition in shared
+ * mode succeeded and subsequent shared-mode acquires might
+ * also succeed, in which case a subsequent waiting thread
+ * must check availability. (Support for three different
+ * return values enables this method to be used in contexts
+ * where acquires only sometimes act exclusively.) Upon
+ * success, this object has been acquired.
+ * @throws IllegalMonitorStateException if acquiring would place this
+ * synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if shared mode is not supported
+ */
+ protected int tryAcquireShared(int arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Attempts to set the state to reflect a release in shared mode.
+ *
+ * <p>This method is always invoked by the thread performing release.
+ *
+ * <p>The default implementation throws
+ * {@link UnsupportedOperationException}.
+ *
+ * @param arg the release argument. This value is always the one
+ * passed to a release method, or the current state value upon
+ * entry to a condition wait. The value is otherwise
+ * uninterpreted and can represent anything you like.
+ * @return {@code true} if this release of shared mode may permit a
+ * waiting acquire (shared or exclusive) to succeed; and
+ * {@code false} otherwise
+ * @throws IllegalMonitorStateException if releasing would place this
+ * synchronizer in an illegal state. This exception must be
+ * thrown in a consistent fashion for synchronization to work
+ * correctly.
+ * @throws UnsupportedOperationException if shared mode is not supported
+ */
+ protected boolean tryReleaseShared(int arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns {@code true} if synchronization is held exclusively with
+ * respect to the current (calling) thread. This method is invoked
+ * upon each call to a non-waiting {@link ConditionObject} method.
+ * (Waiting methods instead invoke {@link #release}.)
+ *
+ * <p>The default implementation throws {@link
+ * UnsupportedOperationException}. This method is invoked
+ * internally only within {@link ConditionObject} methods, so need
+ * not be defined if conditions are not used.
+ *
+ * @return {@code true} if synchronization is held exclusively;
+ * {@code false} otherwise
+ * @throws UnsupportedOperationException if conditions are not supported
+ */
+ protected boolean isHeldExclusively() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * 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. This method can be used
+ * to implement method {@link Lock#lock}.
+ *
+ * @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) {
+ if (!tryAcquire(arg) &&
+ acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
+ selfInterrupt();
+ }
+
+ /**
+ * Acquires in exclusive mode, aborting if interrupted.
+ * Implemented by first checking interrupt status, then invoking
+ * at least once {@link #tryAcquire}, returning on
+ * success. Otherwise the thread is queued, possibly repeatedly
+ * blocking and unblocking, invoking {@link #tryAcquire}
+ * until success or the thread is interrupted. This method can be
+ * used to implement method {@link Lock#lockInterruptibly}.
+ *
+ * @param arg the acquire argument. This value is conveyed to
+ * {@link #tryAcquire} but is otherwise uninterpreted and
+ * can represent anything you like.
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final void acquireInterruptibly(int arg) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ if (!tryAcquire(arg))
+ doAcquireInterruptibly(arg);
+ }
+
+ /**
+ * Attempts to acquire in exclusive mode, aborting if interrupted,
+ * and failing if the given timeout elapses. Implemented by first
+ * checking interrupt status, then invoking at least once {@link
+ * #tryAcquire}, returning on success. Otherwise, the thread is
+ * queued, possibly repeatedly blocking and unblocking, invoking
+ * {@link #tryAcquire} until success or the thread is interrupted
+ * or the timeout elapses. This method can be used to implement
+ * method {@link Lock#tryLock(long, TimeUnit)}.
+ *
+ * @param arg the acquire argument. This value is conveyed to
+ * {@link #tryAcquire} but is otherwise uninterpreted and
+ * can represent anything you like.
+ * @param nanosTimeout the maximum number of nanoseconds to wait
+ * @return {@code true} if acquired; {@code false} if timed out
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ return tryAcquire(arg) ||
+ doAcquireNanos(arg, nanosTimeout);
+ }
+
+ /**
+ * Releases in exclusive mode. Implemented by unblocking one or
+ * more threads if {@link #tryRelease} returns true.
+ * This method can be used to implement method {@link Lock#unlock}.
+ *
+ * @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) {
+ if (tryRelease(arg)) {
+ Node h = head;
+ if (h != null && h.waitStatus != 0)
+ unparkSuccessor(h);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Acquires in shared mode, ignoring interrupts. Implemented by
+ * first invoking at least once {@link #tryAcquireShared},
+ * returning on success. Otherwise the thread is queued, possibly
+ * repeatedly blocking and unblocking, invoking {@link
+ * #tryAcquireShared} until success.
+ *
+ * @param arg the acquire argument. This value is conveyed to
+ * {@link #tryAcquireShared} but is otherwise uninterpreted
+ * and can represent anything you like.
+ */
+ public final void acquireShared(int arg) {
+ if (tryAcquireShared(arg) < 0)
+ doAcquireShared(arg);
+ }
+
+ /**
+ * Acquires in shared mode, aborting if interrupted. Implemented
+ * by first checking interrupt status, then invoking at least once
+ * {@link #tryAcquireShared}, returning on success. Otherwise the
+ * thread is queued, possibly repeatedly blocking and unblocking,
+ * invoking {@link #tryAcquireShared} until success or the thread
+ * is interrupted.
+ * @param arg the acquire argument.
+ * This value is conveyed to {@link #tryAcquireShared} but is
+ * otherwise uninterpreted and can represent anything
+ * you like.
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final void acquireSharedInterruptibly(int arg) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ if (tryAcquireShared(arg) < 0)
+ doAcquireSharedInterruptibly(arg);
+ }
+
+ /**
+ * Attempts to acquire in shared mode, aborting if interrupted, and
+ * failing if the given timeout elapses. Implemented by first
+ * checking interrupt status, then invoking at least once {@link
+ * #tryAcquireShared}, returning on success. Otherwise, the
+ * thread is queued, possibly repeatedly blocking and unblocking,
+ * invoking {@link #tryAcquireShared} until success or the thread
+ * is interrupted or the timeout elapses.
+ *
+ * @param arg the acquire argument. This value is conveyed to
+ * {@link #tryAcquireShared} but is otherwise uninterpreted
+ * and can represent anything you like.
+ * @param nanosTimeout the maximum number of nanoseconds to wait
+ * @return {@code true} if acquired; {@code false} if timed out
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ return tryAcquireShared(arg) >= 0 ||
+ doAcquireSharedNanos(arg, nanosTimeout);
+ }
+
+ /**
+ * 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) {
+ if (tryReleaseShared(arg)) {
+ Node h = head;
+ if (h != null && h.waitStatus != 0)
+ unparkSuccessor(h);
+ return true;
+ }
+ return false;
+ }
+
+ // Queue inspection methods
+
+ /**
+ * Queries whether any threads are waiting to acquire. Note that
+ * because cancellations due to interrupts and timeouts may occur
+ * at any time, a {@code true} return does not guarantee that any
+ * other thread will ever acquire.
+ *
+ * <p>In this implementation, this operation returns in
+ * constant time.
+ *
+ * @return {@code true} if there may be other threads waiting to acquire
+ */
+ public final boolean hasQueuedThreads() {
+ return head != tail;
+ }
+
+ /**
+ * Queries whether any threads have ever contended to acquire this
+ * synchronizer; that is if an acquire method has ever blocked.
+ *
+ * <p>In this implementation, this operation returns in
+ * constant time.
+ *
+ * @return {@code true} if there has ever been contention
+ */
+ public final boolean hasContended() {
+ return head != null;
+ }
+
+ /**
+ * Returns the first (longest-waiting) thread in the queue, or
+ * {@code null} if no threads are currently queued.
+ *
+ * <p>In this implementation, this operation normally returns in
+ * constant time, but may iterate upon contention if other threads are
+ * concurrently modifying the queue.
+ *
+ * @return the first (longest-waiting) thread in the queue, or
+ * {@code null} if no threads are currently queued
+ */
+ public final Thread getFirstQueuedThread() {
+ // handle only fast path, else relay
+ return (head == tail)? null : fullGetFirstQueuedThread();
+ }
+
+ /**
+ * Version of getFirstQueuedThread called when fastpath fails
+ */
+ private Thread fullGetFirstQueuedThread() {
+ /*
+ * The first node is normally h.next. Try to get its
+ * thread field, ensuring consistent reads: If thread
+ * field is nulled out or s.prev is no longer head, then
+ * some other thread(s) concurrently performed setHead in
+ * between some of our reads. We try this twice before
+ * resorting to traversal.
+ */
+ Node h, s;
+ Thread st;
+ if (((h = head) != null && (s = h.next) != null &&
+ s.prev == head && (st = s.thread) != null) ||
+ ((h = head) != null && (s = h.next) != null &&
+ s.prev == head && (st = s.thread) != null))
+ return st;
+
+ /*
+ * Head's next field might not have been set yet, or may have
+ * been unset after setHead. So we must check to see if tail
+ * is actually first node. If not, we continue on, safely
+ * traversing from tail back to head to find first,
+ * guaranteeing termination.
+ */
+
+ Node t = tail;
+ Thread firstThread = null;
+ while (t != null && t != head) {
+ Thread tt = t.thread;
+ if (tt != null)
+ firstThread = tt;
+ t = t.prev;
+ }
+ return firstThread;
+ }
+
+ /**
+ * Returns true if the given thread is currently queued.
+ *
+ * <p>This implementation traverses the queue to determine
+ * presence of the given thread.
+ *
+ * @param thread the thread
+ * @return {@code true} if the given thread is on the queue
+ * @throws NullPointerException if the thread is null
+ */
+ public final boolean isQueued(Thread thread) {
+ if (thread == null)
+ throw new NullPointerException();
+ for (Node p = tail; p != null; p = p.prev)
+ if (p.thread == thread)
+ return true;
+ return false;
+ }
+
+ /**
+ * Return {@code true} if the apparent first queued thread, if one
+ * exists, is not waiting in exclusive mode. Used only as a heuristic
+ * in ReentrantReadWriteLock.
+ */
+ final boolean apparentlyFirstQueuedIsExclusive() {
+ Node h, s;
+ return ((h = head) != null && (s = h.next) != null &&
+ s.nextWaiter != Node.SHARED);
+ }
+
+ /**
+ * Return {@code true} if the queue is empty or if the given thread
+ * is at the head of the queue. This is reliable only if
+ * <tt>current</tt> is actually Thread.currentThread() of caller.
+ */
+ final boolean isFirst(Thread current) {
+ Node h, s;
+ return ((h = head) == null ||
+ ((s = h.next) != null && s.thread == current) ||
+ fullIsFirst(current));
+ }
+
+ final boolean fullIsFirst(Thread current) {
+ // same idea as fullGetFirstQueuedThread
+ Node h, s;
+ Thread firstThread = null;
+ if (((h = head) != null && (s = h.next) != null &&
+ s.prev == head && (firstThread = s.thread) != null))
+ return firstThread == current;
+ Node t = tail;
+ while (t != null && t != head) {
+ Thread tt = t.thread;
+ if (tt != null)
+ firstThread = tt;
+ t = t.prev;
+ }
+ return firstThread == current || firstThread == null;
+ }
+
+
+ // Instrumentation and monitoring methods
+
+ /**
+ * Returns an estimate of the number of threads waiting to
+ * acquire. The value is only an estimate because the number of
+ * threads may change dynamically while this method traverses
+ * internal data structures. This method is designed for use in
+ * monitoring system state, not for synchronization
+ * control.
+ *
+ * @return the estimated number of threads waiting to acquire
+ */
+ public final int getQueueLength() {
+ int n = 0;
+ for (Node p = tail; p != null; p = p.prev) {
+ if (p.thread != null)
+ ++n;
+ }
+ return n;
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire. Because the actual set of threads may change
+ * dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive monitoring facilities.
+ *
+ * @return the collection of threads
+ */
+ public final Collection<Thread> getQueuedThreads() {
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node p = tail; p != null; p = p.prev) {
+ Thread t = p.thread;
+ if (t != null)
+ list.add(t);
+ }
+ return list;
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire in exclusive mode. This has the same properties
+ * as {@link #getQueuedThreads} except that it only returns
+ * those threads waiting due to an exclusive acquire.
+ *
+ * @return the collection of threads
+ */
+ public final Collection<Thread> getExclusiveQueuedThreads() {
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node p = tail; p != null; p = p.prev) {
+ if (!p.isShared()) {
+ Thread t = p.thread;
+ if (t != null)
+ list.add(t);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire in shared mode. This has the same properties
+ * as {@link #getQueuedThreads} except that it only returns
+ * those threads waiting due to a shared acquire.
+ *
+ * @return the collection of threads
+ */
+ public final Collection<Thread> getSharedQueuedThreads() {
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node p = tail; p != null; p = p.prev) {
+ if (p.isShared()) {
+ Thread t = p.thread;
+ if (t != null)
+ list.add(t);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Returns a string identifying this synchronizer, as well as its state.
+ * The state, in brackets, includes the String {@code "State ="}
+ * followed by the current value of {@link #getState}, and either
+ * {@code "nonempty"} or {@code "empty"} depending on whether the
+ * queue is empty.
+ *
+ * @return a string identifying this synchronizer, as well as its state
+ */
+ public String toString() {
+ int s = getState();
+ String q = hasQueuedThreads()? "non" : "";
+ return super.toString() +
+ "[State = " + s + ", " + q + "empty queue]";
+ }
+
+
+ // Internal support methods for Conditions
+
+ /**
+ * Returns true if a node, always one that was initially placed on
+ * a condition queue, is now waiting to reacquire on sync queue.
+ * @param node the node
+ * @return true if is reacquiring
+ */
+ final boolean isOnSyncQueue(Node node) {
+ if (node.waitStatus == Node.CONDITION || node.prev == null)
+ return false;
+ if (node.next != null) // If has successor, it must be on queue
+ return true;
+ /*
+ * node.prev can be non-null, but not yet on queue because
+ * the CAS to place it on queue can fail. So we have to
+ * traverse from tail to make sure it actually made it. It
+ * will always be near the tail in calls to this method, and
+ * unless the CAS failed (which is unlikely), it will be
+ * there, so we hardly ever traverse much.
+ */
+ return findNodeFromTail(node);
+ }
+
+ /**
+ * Returns true if node is on sync queue by searching backwards from tail.
+ * Called only when needed by isOnSyncQueue.
+ * @return true if present
+ */
+ private boolean findNodeFromTail(Node node) {
+ Node t = tail;
+ for (;;) {
+ if (t == node)
+ return true;
+ if (t == null)
+ return false;
+ t = t.prev;
+ }
+ }
+
+ /**
+ * Transfers a node from a condition queue onto sync queue.
+ * Returns true if successful.
+ * @param node the node
+ * @return true if successfully transferred (else the node was
+ * cancelled before signal).
+ */
+ final boolean transferForSignal(Node node) {
+ /*
+ * If cannot change waitStatus, the node has been cancelled.
+ */
+ if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
+ return false;
+
+ /*
+ * 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).
+ */
+ Node p = enq(node);
+ int c = p.waitStatus;
+ if (c > 0 || !compareAndSetWaitStatus(p, c, Node.SIGNAL))
+ LockSupport.unpark(node.thread);
+ return true;
+ }
+
+ /**
+ * Transfers node, if necessary, to sync queue after a cancelled
+ * wait. Returns true if thread was cancelled before being
+ * signalled.
+ * @param current the waiting thread
+ * @param node its node
+ * @return true if cancelled before the node was signalled.
+ */
+ final boolean transferAfterCancelledWait(Node node) {
+ if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
+ enq(node);
+ return true;
+ }
+ /*
+ * If we lost out to a signal(), then we can't proceed
+ * until it finishes its enq(). Cancelling during an
+ * incomplete transfer is both rare and transient, so just
+ * spin.
+ */
+ while (!isOnSyncQueue(node))
+ Thread.yield();
+ return false;
+ }
+
+ /**
+ * Invokes release with current state value; returns saved state.
+ * Cancels node and throws exception on failure.
+ * @param node the condition node for this wait
+ * @return previous sync state
+ */
+ final int fullyRelease(Node node) {
+ try {
+ int savedState = getState();
+ if (release(savedState))
+ return savedState;
+ } catch (RuntimeException ex) {
+ node.waitStatus = Node.CANCELLED;
+ throw ex;
+ }
+ // reach here if release fails
+ node.waitStatus = Node.CANCELLED;
+ throw new IllegalMonitorStateException();
+ }
+
+ // Instrumentation methods for conditions
+
+ /**
+ * Queries whether the given ConditionObject
+ * uses this synchronizer as its lock.
+ *
+ * @param condition the condition
+ * @return <tt>true</tt> if owned
+ * @throws NullPointerException if the condition is null
+ */
+ public final boolean owns(ConditionObject condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ return condition.isOwnedBy(this);
+ }
+
+ /**
+ * Queries whether any threads are waiting on the given condition
+ * associated with this synchronizer. Note that because timeouts
+ * and interrupts may occur at any time, a <tt>true</tt> return
+ * does not guarantee that a future <tt>signal</tt> will awaken
+ * any threads. This method is designed primarily for use in
+ * monitoring of the system state.
+ *
+ * @param condition the condition
+ * @return <tt>true</tt> if there are any waiting threads
+ * @throws IllegalMonitorStateException if exclusive synchronization
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this synchronizer
+ * @throws NullPointerException if the condition is null
+ */
+ public final boolean hasWaiters(ConditionObject condition) {
+ if (!owns(condition))
+ throw new IllegalArgumentException("Not owner");
+ return condition.hasWaiters();
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting on the
+ * given condition associated with this synchronizer. Note that
+ * because timeouts and interrupts may occur at any time, the
+ * estimate serves only as an upper bound on the actual number of
+ * waiters. This method is designed for use in monitoring of the
+ * system state, not for synchronization control.
+ *
+ * @param condition the condition
+ * @return the estimated number of waiting threads
+ * @throws IllegalMonitorStateException if exclusive synchronization
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this synchronizer
+ * @throws NullPointerException if the condition is null
+ */
+ public final int getWaitQueueLength(ConditionObject condition) {
+ if (!owns(condition))
+ throw new IllegalArgumentException("Not owner");
+ return condition.getWaitQueueLength();
+ }
+
+ /**
+ * Returns a collection containing those threads that may be
+ * waiting on the given condition associated with this
+ * synchronizer. Because the actual set of threads may change
+ * dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order.
+ *
+ * @param condition the condition
+ * @return the collection of threads
+ * @throws IllegalMonitorStateException if exclusive synchronization
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this synchronizer
+ * @throws NullPointerException if the condition is null
+ */
+ public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
+ if (!owns(condition))
+ throw new IllegalArgumentException("Not owner");
+ return condition.getWaitingThreads();
+ }
+
+ /**
+ * Condition implementation for a {@link
+ * AbstractQueuedSynchronizer} serving as the basis of a {@link
+ * Lock} implementation.
+ *
+ * <p>Method documentation for this class describes mechanics,
+ * not behavioral specifications from the point of view of Lock
+ * and Condition users. Exported versions of this class will in
+ * general need to be accompanied by documentation describing
+ * condition semantics that rely on those of the associated
+ * <tt>AbstractQueuedSynchronizer</tt>.
+ *
+ * <p>This class is Serializable, but all fields are transient,
+ * so deserialized conditions have no waiters.
+ */
+ public class ConditionObject implements Condition, java.io.Serializable {
+ private static final long serialVersionUID = 1173984872572414699L;
+ /** First node of condition queue. */
+ private transient Node firstWaiter;
+ /** Last node of condition queue. */
+ private transient Node lastWaiter;
+
+ /**
+ * Creates a new <tt>ConditionObject</tt> instance.
+ */
+ public ConditionObject() { }
+
+ // Internal methods
+
+ /**
+ * Adds a new waiter to wait queue.
+ * @return its new wait node
+ */
+ private Node addConditionWaiter() {
+ Node node = new Node(Thread.currentThread(), Node.CONDITION);
+ Node t = lastWaiter;
+ if (t == null)
+ firstWaiter = node;
+ else
+ t.nextWaiter = node;
+ lastWaiter = node;
+ return node;
+ }
+
+ /**
+ * Removes and transfers nodes until hit non-cancelled one or
+ * null. Split out from signal in part to encourage compilers
+ * to inline the case of no waiters.
+ * @param first (non-null) the first node on condition queue
+ */
+ private void doSignal(Node first) {
+ do {
+ if ( (firstWaiter = first.nextWaiter) == null)
+ lastWaiter = null;
+ first.nextWaiter = null;
+ } while (!transferForSignal(first) &&
+ (first = firstWaiter) != null);
+ }
+
+ /**
+ * Removes and transfers all nodes.
+ * @param first (non-null) the first node on condition queue
+ */
+ private void doSignalAll(Node first) {
+ lastWaiter = firstWaiter = null;
+ do {
+ Node next = first.nextWaiter;
+ first.nextWaiter = null;
+ transferForSignal(first);
+ first = next;
+ } while (first != null);
+ }
+
+ /**
+ * Returns true if given node is on this condition queue.
+ * Call only when holding lock.
+ */
+ private boolean isOnConditionQueue(Node node) {
+ return node.next != null || node == lastWaiter;
+ }
+
+ /**
+ * Unlinks a cancelled waiter node from condition queue. This
+ * is called when cancellation occurred during condition wait,
+ * not lock wait, and is called only after lock has been
+ * re-acquired by a cancelled waiter and the node is not known
+ * to already have been dequeued. It is needed to avoid
+ * garbage retention in the absence of signals. So even though
+ * it may require a full traversal, it comes into play only
+ * when timeouts or cancellations occur in the absence of
+ * signals.
+ */
+ private void unlinkCancelledWaiter(Node node) {
+ Node t = firstWaiter;
+ Node trail = null;
+ while (t != null) {
+ if (t == node) {
+ Node next = t.nextWaiter;
+ if (trail == null)
+ firstWaiter = next;
+ else
+ trail.nextWaiter = next;
+ if (lastWaiter == node)
+ lastWaiter = trail;
+ break;
+ }
+ trail = t;
+ t = t.nextWaiter;
+ }
+ }
+
+ // public methods
+
+ /**
+ * Moves the longest-waiting thread, if one exists, from the
+ * wait queue for this condition to the wait queue for the
+ * owning lock.
+ *
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns {@code false}
+ */
+ public final void signal() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ Node first = firstWaiter;
+ if (first != null)
+ doSignal(first);
+ }
+
+ /**
+ * Moves all threads from the wait queue for this condition to
+ * the wait queue for the owning lock.
+ *
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns {@code false}
+ */
+ public final void signalAll() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ Node first = firstWaiter;
+ if (first != null)
+ doSignalAll(first);
+ }
+
+ /**
+ * Implements uninterruptible condition wait.
+ * <ol>
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * </ol>
+ */
+ public final void awaitUninterruptibly() {
+ Node node = addConditionWaiter();
+ int savedState = fullyRelease(node);
+ boolean interrupted = false;
+ while (!isOnSyncQueue(node)) {
+ LockSupport.park(this);
+ if (Thread.interrupted())
+ interrupted = true;
+ }
+ if (acquireQueued(node, savedState) || interrupted)
+ selfInterrupt();
+ }
+
+ /*
+ * For interruptible waits, we need to track whether to throw
+ * InterruptedException, if interrupted while blocked on
+ * condition, versus reinterrupt current thread, if
+ * interrupted while blocked waiting to re-acquire.
+ */
+
+ /** Mode meaning to reinterrupt on exit from wait */
+ private static final int REINTERRUPT = 1;
+ /** Mode meaning to throw InterruptedException on exit from wait */
+ private static final int THROW_IE = -1;
+
+ /**
+ * Checks for interrupt, returning THROW_IE if interrupted
+ * before signalled, REINTERRUPT if after signalled, or
+ * 0 if not interrupted.
+ */
+ private int checkInterruptWhileWaiting(Node node) {
+ return (Thread.interrupted()) ?
+ ((transferAfterCancelledWait(node))? THROW_IE : REINTERRUPT) :
+ 0;
+ }
+
+ /**
+ * Throws InterruptedException, reinterrupts current thread, or
+ * does nothing, depending on mode.
+ */
+ private void reportInterruptAfterWait(int interruptMode)
+ throws InterruptedException {
+ if (interruptMode == THROW_IE)
+ throw new InterruptedException();
+ else if (interruptMode == REINTERRUPT)
+ selfInterrupt();
+ }
+
+ /**
+ * Implements interruptible condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled or interrupted
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw exception
+ * </ol>
+ */
+ public final void await() throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ int savedState = fullyRelease(node);
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ LockSupport.park(this);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (isOnConditionQueue(node))
+ unlinkCancelledWaiter(node);
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ }
+
+ /**
+ * Implements timed condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled, interrupted, or timed out
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw InterruptedException
+ * </ol>
+ */
+ public final long awaitNanos(long nanosTimeout) throws InterruptedException {
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ int savedState = fullyRelease(node);
+ long lastTime = System.nanoTime();
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ if (nanosTimeout <= 0L) {
+ transferAfterCancelledWait(node);
+ break;
+ }
+ LockSupport.parkNanos(this, nanosTimeout);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (isOnConditionQueue(node))
+ unlinkCancelledWaiter(node);
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ return nanosTimeout - (System.nanoTime() - lastTime);
+ }
+
+ /**
+ * Implements absolute timed condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled, interrupted, or timed out
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw InterruptedException
+ * <li> If timed out while blocked in step 4, return false, else true
+ * </ol>
+ */
+ public final boolean awaitUntil(Date deadline) throws InterruptedException {
+ if (deadline == null)
+ throw new NullPointerException();
+ long abstime = deadline.getTime();
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ int savedState = fullyRelease(node);
+ boolean timedout = false;
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ if (System.currentTimeMillis() > abstime) {
+ timedout = transferAfterCancelledWait(node);
+ break;
+ }
+ LockSupport.parkUntil(this, abstime);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (isOnConditionQueue(node))
+ unlinkCancelledWaiter(node);
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ return !timedout;
+ }
+
+ /**
+ * Implements timed condition wait.
+ * <ol>
+ * <li> If current thread is interrupted, throw InterruptedException
+ * <li> Save lock state returned by {@link #getState}
+ * <li> Invoke {@link #release} with
+ * saved state as argument, throwing
+ * IllegalMonitorStateException if it fails.
+ * <li> Block until signalled, interrupted, or timed out
+ * <li> Reacquire by invoking specialized version of
+ * {@link #acquire} with saved state as argument.
+ * <li> If interrupted while blocked in step 4, throw InterruptedException
+ * <li> If timed out while blocked in step 4, return false, else true
+ * </ol>
+ */
+ public final boolean await(long time, TimeUnit unit) throws InterruptedException {
+ if (unit == null)
+ throw new NullPointerException();
+ long nanosTimeout = unit.toNanos(time);
+ if (Thread.interrupted())
+ throw new InterruptedException();
+ Node node = addConditionWaiter();
+ int savedState = fullyRelease(node);
+ long lastTime = System.nanoTime();
+ boolean timedout = false;
+ int interruptMode = 0;
+ while (!isOnSyncQueue(node)) {
+ if (nanosTimeout <= 0L) {
+ timedout = transferAfterCancelledWait(node);
+ break;
+ }
+ LockSupport.parkNanos(this, nanosTimeout);
+ if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
+ break;
+ long now = System.nanoTime();
+ nanosTimeout -= now - lastTime;
+ lastTime = now;
+ }
+ if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
+ interruptMode = REINTERRUPT;
+ if (isOnConditionQueue(node))
+ unlinkCancelledWaiter(node);
+ if (interruptMode != 0)
+ reportInterruptAfterWait(interruptMode);
+ return !timedout;
+ }
+
+ // support for instrumentation
+
+ /**
+ * Returns true if this condition was created by the given
+ * synchronization object.
+ *
+ * @return {@code true} if owned
+ */
+ final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
+ return sync == AbstractQueuedSynchronizer.this;
+ }
+
+ /**
+ * Queries whether any threads are waiting on this condition.
+ * Implements {@link AbstractQueuedSynchronizer#hasWaiters}.
+ *
+ * @return {@code true} if there are any waiting threads
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns {@code false}
+ */
+ protected final boolean hasWaiters() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+ if (w.waitStatus == Node.CONDITION)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting on
+ * this condition.
+ * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength}.
+ *
+ * @return the estimated number of waiting threads
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns {@code false}
+ */
+ protected final int getWaitQueueLength() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ int n = 0;
+ for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+ if (w.waitStatus == Node.CONDITION)
+ ++n;
+ }
+ return n;
+ }
+
+ /**
+ * Returns a collection containing those threads that may be
+ * waiting on this Condition.
+ * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads}.
+ *
+ * @return the collection of threads
+ * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
+ * returns {@code false}
+ */
+ protected final Collection<Thread> getWaitingThreads() {
+ if (!isHeldExclusively())
+ throw new IllegalMonitorStateException();
+ ArrayList<Thread> list = new ArrayList<Thread>();
+ for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
+ if (w.waitStatus == Node.CONDITION) {
+ Thread t = w.thread;
+ if (t != null)
+ list.add(t);
+ }
+ }
+ return list;
+ }
+ }
+
+ /**
+ * Setup to support compareAndSet. We need to natively implement
+ * this here: For the sake of permitting future enhancements, we
+ * cannot explicitly subclass AtomicInteger, which would be
+ * efficient and useful otherwise. So, as the lesser of evils, we
+ * natively implement using hotspot intrinsics API. And while we
+ * are at it, we do the same for other CASable fields (which could
+ * otherwise be done with atomic field updaters).
+ */
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final long stateOffset;
+ private static final long headOffset;
+ private static final long tailOffset;
+ private static final long waitStatusOffset;
+
+ static {
+ try {
+ stateOffset = unsafe.objectFieldOffset
+ (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
+ headOffset = unsafe.objectFieldOffset
+ (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
+ tailOffset = unsafe.objectFieldOffset
+ (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
+ waitStatusOffset = unsafe.objectFieldOffset
+ (Node.class.getDeclaredField("waitStatus"));
+
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
+ /**
+ * CAS head field. Used only by enq
+ */
+ private final boolean compareAndSetHead(Node update) {
+ return unsafe.compareAndSwapObject(this, headOffset, null, update);
+ }
+
+ /**
+ * CAS tail field. Used only by enq
+ */
+ private final boolean compareAndSetTail(Node expect, Node update) {
+ return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
+ }
+
+ /**
+ * CAS waitStatus field of a node.
+ */
+ private final static boolean compareAndSetWaitStatus(Node node,
+ int expect,
+ int update) {
+ return unsafe.compareAndSwapInt(node, waitStatusOffset,
+ expect, update);
+ }
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/Condition.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/Condition.java
new file mode 100644
index 000000000..5d24128e1
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/Condition.java
@@ -0,0 +1,435 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.concurrent.*;
+import java.util.Date;
+
+/**
+ * {@code Condition} factors out the {@code Object} monitor
+ * methods ({@link Object#wait() wait}, {@link Object#notify notify}
+ * and {@link Object#notifyAll notifyAll}) into distinct objects to
+ * give the effect of having multiple wait-sets per object, by
+ * combining them with the use of arbitrary {@link Lock} implementations.
+ * Where a {@code Lock} replaces the use of {@code synchronized} methods
+ * and statements, a {@code Condition} replaces the use of the Object
+ * monitor methods.
+ *
+ * <p>Conditions (also known as <em>condition queues</em> or
+ * <em>condition variables</em>) provide a means for one thread to
+ * suspend execution (to &quot;wait&quot;) until notified by another
+ * thread that some state condition may now be true. Because access
+ * to this shared state information occurs in different threads, it
+ * must be protected, so a lock of some form is associated with the
+ * condition. The key property that waiting for a condition provides
+ * is that it <em>atomically</em> releases the associated lock and
+ * suspends the current thread, just like {@code Object.wait}.
+ *
+ * <p>A {@code Condition} instance is intrinsically bound to a lock.
+ * To obtain a {@code Condition} instance for a particular {@link Lock}
+ * instance use its {@link Lock#newCondition newCondition()} method.
+ *
+ * <p>As an example, suppose we have a bounded buffer which supports
+ * {@code put} and {@code take} methods. If a
+ * {@code take} is attempted on an empty buffer, then the thread will block
+ * until an item becomes available; if a {@code put} is attempted on a
+ * full buffer, then the thread will block until a space becomes available.
+ * We would like to keep waiting {@code put} threads and {@code take}
+ * threads in separate wait-sets so that we can use the optimization of
+ * only notifying a single thread at a time when items or spaces become
+ * available in the buffer. This can be achieved using two
+ * {@link Condition} instances.
+ * <pre>
+ * class BoundedBuffer {
+ * <b>final Lock lock = new ReentrantLock();</b>
+ * final Condition notFull = <b>lock.newCondition(); </b>
+ * final Condition notEmpty = <b>lock.newCondition(); </b>
+ *
+ * final Object[] items = new Object[100];
+ * int putptr, takeptr, count;
+ *
+ * public void put(Object x) throws InterruptedException {
+ * <b>lock.lock();
+ * try {</b>
+ * while (count == items.length)
+ * <b>notFull.await();</b>
+ * items[putptr] = x;
+ * if (++putptr == items.length) putptr = 0;
+ * ++count;
+ * <b>notEmpty.signal();</b>
+ * <b>} finally {
+ * lock.unlock();
+ * }</b>
+ * }
+ *
+ * public Object take() throws InterruptedException {
+ * <b>lock.lock();
+ * try {</b>
+ * while (count == 0)
+ * <b>notEmpty.await();</b>
+ * Object x = items[takeptr];
+ * if (++takeptr == items.length) takeptr = 0;
+ * --count;
+ * <b>notFull.signal();</b>
+ * return x;
+ * <b>} finally {
+ * lock.unlock();
+ * }</b>
+ * }
+ * }
+ * </pre>
+ *
+ * (The {@link java.util.concurrent.ArrayBlockingQueue} class provides
+ * this functionality, so there is no reason to implement this
+ * sample usage class.)
+ *
+ * <p>A {@code Condition} implementation can provide behavior and semantics
+ * that is
+ * different from that of the {@code Object} monitor methods, such as
+ * guaranteed ordering for notifications, or not requiring a lock to be held
+ * when performing notifications.
+ * If an implementation provides such specialized semantics then the
+ * implementation must document those semantics.
+ *
+ * <p>Note that {@code Condition} instances are just normal objects and can
+ * themselves be used as the target in a {@code synchronized} statement,
+ * and can have their own monitor {@link Object#wait wait} and
+ * {@link Object#notify notification} methods invoked.
+ * Acquiring the monitor lock of a {@code Condition} instance, or using its
+ * monitor methods, has no specified relationship with acquiring the
+ * {@link Lock} associated with that {@code Condition} or the use of its
+ * {@linkplain #await waiting} and {@linkplain #signal signalling} methods.
+ * It is recommended that to avoid confusion you never use {@code Condition}
+ * instances in this way, except perhaps within their own implementation.
+ *
+ * <p>Except where noted, passing a {@code null} value for any parameter
+ * will result in a {@link NullPointerException} being thrown.
+ *
+ * <h3>Implementation Considerations</h3>
+ *
+ * <p>When waiting upon a {@code Condition}, a &quot;<em>spurious
+ * wakeup</em>&quot; is permitted to occur, in
+ * general, as a concession to the underlying platform semantics.
+ * This has little practical impact on most application programs as a
+ * {@code Condition} should always be waited upon in a loop, testing
+ * the state predicate that is being waited for. An implementation is
+ * free to remove the possibility of spurious wakeups but it is
+ * recommended that applications programmers always assume that they can
+ * occur and so always wait in a loop.
+ *
+ * <p>The three forms of condition waiting
+ * (interruptible, non-interruptible, and timed) may differ in their ease of
+ * implementation on some platforms and in their performance characteristics.
+ * In particular, it may be difficult to provide these features and maintain
+ * specific semantics such as ordering guarantees.
+ * Further, the ability to interrupt the actual suspension of the thread may
+ * not always be feasible to implement on all platforms.
+ *
+ * <p>Consequently, an implementation is not required to define exactly the
+ * same guarantees or semantics for all three forms of waiting, nor is it
+ * required to support interruption of the actual suspension of the thread.
+ *
+ * <p>An implementation is required to
+ * clearly document the semantics and guarantees provided by each of the
+ * waiting methods, and when an implementation does support interruption of
+ * thread suspension then it must obey the interruption semantics as defined
+ * in this interface.
+ *
+ * <p>As interruption generally implies cancellation, and checks for
+ * interruption are often infrequent, an implementation can favor responding
+ * to an interrupt over normal method return. This is true even if it can be
+ * shown that the interrupt occurred after another action may have unblocked
+ * the thread. An implementation should document this behavior.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface Condition {
+
+ /**
+ * Causes the current thread to wait until it is signalled or
+ * {@linkplain Thread#interrupt interrupted}.
+ *
+ * <p>The lock associated with this {@code Condition} is atomically
+ * released and the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until <em>one</em> of four things happens:
+ * <ul>
+ * <li>Some other thread invokes the {@link #signal} method for this
+ * {@code Condition} and the current thread happens to be chosen as the
+ * thread to be awakened; or
+ * <li>Some other thread invokes the {@link #signalAll} method for this
+ * {@code Condition}; or
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+ * current thread, and interruption of thread suspension is supported; or
+ * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
+ * </ul>
+ *
+ * <p>In all cases, before this method can return the current thread must
+ * re-acquire the lock associated with this condition. When the
+ * thread returns it is <em>guaranteed</em> to hold this lock.
+ *
+ * <p>If the current thread:
+ * <ul>
+ * <li>has its interrupted status set on entry to this method; or
+ * <li>is {@linkplain Thread#interrupt interrupted} while waiting
+ * and interruption of thread suspension is supported,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared. It is not specified, in the first
+ * case, whether or not the test for interruption occurs before the lock
+ * is released.
+ *
+ * <p><b>Implementation Considerations</b>
+ *
+ * <p>The current thread is assumed to hold the lock associated with this
+ * {@code Condition} when this method is called.
+ * It is up to the implementation to determine if this is
+ * the case and if not, how to respond. Typically, an exception will be
+ * thrown (such as {@link IllegalMonitorStateException}) and the
+ * implementation must document that fact.
+ *
+ * <p>An implementation can favor responding to an interrupt over normal
+ * method return in response to a signal. In that case the implementation
+ * must ensure that the signal is redirected to another waiting thread, if
+ * there is one.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * (and interruption of thread suspension is supported)
+ */
+ void await() throws InterruptedException;
+
+ /**
+ * Causes the current thread to wait until it is signalled.
+ *
+ * <p>The lock associated with this condition is atomically
+ * released and the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until <em>one</em> of three things happens:
+ * <ul>
+ * <li>Some other thread invokes the {@link #signal} method for this
+ * {@code Condition} and the current thread happens to be chosen as the
+ * thread to be awakened; or
+ * <li>Some other thread invokes the {@link #signalAll} method for this
+ * {@code Condition}; or
+ * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
+ * </ul>
+ *
+ * <p>In all cases, before this method can return the current thread must
+ * re-acquire the lock associated with this condition. When the
+ * thread returns it is <em>guaranteed</em> to hold this lock.
+ *
+ * <p>If the current thread's interrupted status is set when it enters
+ * this method, or it is {@linkplain Thread#interrupt interrupted}
+ * while waiting, it will continue to wait until signalled. When it finally
+ * returns from this method its interrupted status will still
+ * be set.
+ *
+ * <p><b>Implementation Considerations</b>
+ *
+ * <p>The current thread is assumed to hold the lock associated with this
+ * {@code Condition} when this method is called.
+ * It is up to the implementation to determine if this is
+ * the case and if not, how to respond. Typically, an exception will be
+ * thrown (such as {@link IllegalMonitorStateException}) and the
+ * implementation must document that fact.
+ */
+ void awaitUninterruptibly();
+
+ /**
+ * Causes the current thread to wait until it is signalled or interrupted,
+ * or the specified waiting time elapses.
+ *
+ * <p>The lock associated with this condition is atomically
+ * released and the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until <em>one</em> of five things happens:
+ * <ul>
+ * <li>Some other thread invokes the {@link #signal} method for this
+ * {@code Condition} and the current thread happens to be chosen as the
+ * thread to be awakened; or
+ * <li>Some other thread invokes the {@link #signalAll} method for this
+ * {@code Condition}; or
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+ * current thread, and interruption of thread suspension is supported; or
+ * <li>The specified waiting time elapses; or
+ * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
+ * </ul>
+ *
+ * <p>In all cases, before this method can return the current thread must
+ * re-acquire the lock associated with this condition. When the
+ * thread returns it is <em>guaranteed</em> to hold this lock.
+ *
+ * <p>If the current thread:
+ * <ul>
+ * <li>has its interrupted status set on entry to this method; or
+ * <li>is {@linkplain Thread#interrupt interrupted} while waiting
+ * and interruption of thread suspension is supported,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared. It is not specified, in the first
+ * case, whether or not the test for interruption occurs before the lock
+ * is released.
+ *
+ * <p>The method returns an estimate of the number of nanoseconds
+ * remaining to wait given the supplied {@code nanosTimeout}
+ * value upon return, or a value less than or equal to zero if it
+ * timed out. This value can be used to determine whether and how
+ * long to re-wait in cases where the wait returns but an awaited
+ * condition still does not hold. Typical uses of this method take
+ * the following form:
+ *
+ * <pre>
+ * synchronized boolean aMethod(long timeout, TimeUnit unit) {
+ * long nanosTimeout = unit.toNanos(timeout);
+ * while (!conditionBeingWaitedFor) {
+ * if (nanosTimeout &gt; 0)
+ * nanosTimeout = theCondition.awaitNanos(nanosTimeout);
+ * else
+ * return false;
+ * }
+ * // ...
+ * }
+ * </pre>
+ *
+ * <p> Design note: This method requires a nanosecond argument so
+ * as to avoid truncation errors in reporting remaining times.
+ * Such precision loss would make it difficult for programmers to
+ * ensure that total waiting times are not systematically shorter
+ * than specified when re-waits occur.
+ *
+ * <p><b>Implementation Considerations</b>
+ *
+ * <p>The current thread is assumed to hold the lock associated with this
+ * {@code Condition} when this method is called.
+ * It is up to the implementation to determine if this is
+ * the case and if not, how to respond. Typically, an exception will be
+ * thrown (such as {@link IllegalMonitorStateException}) and the
+ * implementation must document that fact.
+ *
+ * <p>An implementation can favor responding to an interrupt over normal
+ * method return in response to a signal, or over indicating the elapse
+ * of the specified waiting time. In either case the implementation
+ * must ensure that the signal is redirected to another waiting thread, if
+ * there is one.
+ *
+ * @param nanosTimeout the maximum time to wait, in nanoseconds
+ * @return an estimate of the {@code nanosTimeout} value minus
+ * the time spent waiting upon return from this method.
+ * A positive value may be used as the argument to a
+ * subsequent call to this method to finish waiting out
+ * the desired time. A value less than or equal to zero
+ * indicates that no time remains.
+ * @throws InterruptedException if the current thread is interrupted
+ * (and interruption of thread suspension is supported)
+ */
+ long awaitNanos(long nanosTimeout) throws InterruptedException;
+
+ /**
+ * Causes the current thread to wait until it is signalled or interrupted,
+ * or the specified waiting time elapses. This method is behaviorally
+ * equivalent to:<br>
+ * <pre>
+ * awaitNanos(unit.toNanos(time)) &gt; 0
+ * </pre>
+ * @param time the maximum time to wait
+ * @param unit the time unit of the {@code time} argument
+ * @return {@code false} if the waiting time detectably elapsed
+ * before return from the method, else {@code true}
+ * @throws InterruptedException if the current thread is interrupted
+ * (and interruption of thread suspension is supported)
+ */
+ boolean await(long time, TimeUnit unit) throws InterruptedException;
+
+ /**
+ * Causes the current thread to wait until it is signalled or interrupted,
+ * or the specified deadline elapses.
+ *
+ * <p>The lock associated with this condition is atomically
+ * released and the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until <em>one</em> of five things happens:
+ * <ul>
+ * <li>Some other thread invokes the {@link #signal} method for this
+ * {@code Condition} and the current thread happens to be chosen as the
+ * thread to be awakened; or
+ * <li>Some other thread invokes the {@link #signalAll} method for this
+ * {@code Condition}; or
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+ * current thread, and interruption of thread suspension is supported; or
+ * <li>The specified deadline elapses; or
+ * <li>A &quot;<em>spurious wakeup</em>&quot; occurs.
+ * </ul>
+ *
+ * <p>In all cases, before this method can return the current thread must
+ * re-acquire the lock associated with this condition. When the
+ * thread returns it is <em>guaranteed</em> to hold this lock.
+ *
+ *
+ * <p>If the current thread:
+ * <ul>
+ * <li>has its interrupted status set on entry to this method; or
+ * <li>is {@linkplain Thread#interrupt interrupted} while waiting
+ * and interruption of thread suspension is supported,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared. It is not specified, in the first
+ * case, whether or not the test for interruption occurs before the lock
+ * is released.
+ *
+ *
+ * <p>The return value indicates whether the deadline has elapsed,
+ * which can be used as follows:
+ * <pre>
+ * synchronized boolean aMethod(Date deadline) {
+ * boolean stillWaiting = true;
+ * while (!conditionBeingWaitedFor) {
+ * if (stillWaiting)
+ * stillWaiting = theCondition.awaitUntil(deadline);
+ * else
+ * return false;
+ * }
+ * // ...
+ * }
+ * </pre>
+ *
+ * <p><b>Implementation Considerations</b>
+ *
+ * <p>The current thread is assumed to hold the lock associated with this
+ * {@code Condition} when this method is called.
+ * It is up to the implementation to determine if this is
+ * the case and if not, how to respond. Typically, an exception will be
+ * thrown (such as {@link IllegalMonitorStateException}) and the
+ * implementation must document that fact.
+ *
+ * <p>An implementation can favor responding to an interrupt over normal
+ * method return in response to a signal, or over indicating the passing
+ * of the specified deadline. In either case the implementation
+ * must ensure that the signal is redirected to another waiting thread, if
+ * there is one.
+ *
+ * @param deadline the absolute time to wait until
+ * @return {@code false} if the deadline has elapsed upon return, else
+ * {@code true}
+ * @throws InterruptedException if the current thread is interrupted
+ * (and interruption of thread suspension is supported)
+ */
+ boolean awaitUntil(Date deadline) throws InterruptedException;
+
+ /**
+ * Wakes up one waiting thread.
+ *
+ * <p>If any threads are waiting on this condition then one
+ * is selected for waking up. That thread must then re-acquire the
+ * lock before returning from {@code await}.
+ */
+ void signal();
+
+ /**
+ * Wakes up all waiting threads.
+ *
+ * <p>If any threads are waiting on this condition then they are
+ * all woken up. Each thread must re-acquire the lock before it can
+ * return from {@code await}.
+ */
+ void signalAll();
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/Lock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/Lock.java
new file mode 100644
index 000000000..4b9abd665
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/Lock.java
@@ -0,0 +1,327 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * {@code Lock} implementations provide more extensive locking
+ * operations than can be obtained using {@code synchronized} methods
+ * and statements. They allow more flexible structuring, may have
+ * quite different properties, and may support multiple associated
+ * {@link Condition} objects.
+ *
+ * <p>A lock is a tool for controlling access to a shared resource by
+ * multiple threads. Commonly, a lock provides exclusive access to a
+ * shared resource: only one thread at a time can acquire the lock and
+ * all access to the shared resource requires that the lock be
+ * acquired first. However, some locks may allow concurrent access to
+ * a shared resource, such as the read lock of a {@link ReadWriteLock}.
+ *
+ * <p>The use of {@code synchronized} methods or statements provides
+ * access to the implicit monitor lock associated with every object, but
+ * forces all lock acquisition and release to occur in a block-structured way:
+ * when multiple locks are acquired they must be released in the opposite
+ * order, and all locks must be released in the same lexical scope in which
+ * they were acquired.
+ *
+ * <p>While the scoping mechanism for {@code synchronized} methods
+ * and statements makes it much easier to program with monitor locks,
+ * and helps avoid many common programming errors involving locks,
+ * there are occasions where you need to work with locks in a more
+ * flexible way. For example, some algorithms for traversing
+ * concurrently accessed data structures require the use of
+ * &quot;hand-over-hand&quot; or &quot;chain locking&quot;: you
+ * acquire the lock of node A, then node B, then release A and acquire
+ * C, then release B and acquire D and so on. Implementations of the
+ * {@code Lock} interface enable the use of such techniques by
+ * allowing a lock to be acquired and released in different scopes,
+ * and allowing multiple locks to be acquired and released in any
+ * order.
+ *
+ * <p>With this increased flexibility comes additional
+ * responsibility. The absence of block-structured locking removes the
+ * automatic release of locks that occurs with {@code synchronized}
+ * methods and statements. In most cases, the following idiom
+ * should be used:
+ *
+ * <pre><tt> Lock l = ...;
+ * l.lock();
+ * try {
+ * // access the resource protected by this lock
+ * } finally {
+ * l.unlock();
+ * }
+ * </tt></pre>
+ *
+ * When locking and unlocking occur in different scopes, care must be
+ * taken to ensure that all code that is executed while the lock is
+ * held is protected by try-finally or try-catch to ensure that the
+ * lock is released when necessary.
+ *
+ * <p>{@code Lock} implementations provide additional functionality
+ * over the use of {@code synchronized} methods and statements by
+ * providing a non-blocking attempt to acquire a lock ({@link
+ * #tryLock()}), an attempt to acquire the lock that can be
+ * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
+ * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
+ *
+ * <p>A {@code Lock} class can also provide behavior and semantics
+ * that is quite different from that of the implicit monitor lock,
+ * such as guaranteed ordering, non-reentrant usage, or deadlock
+ * detection. If an implementation provides such specialized semantics
+ * then the implementation must document those semantics.
+ *
+ * <p>Note that {@code Lock} instances are just normal objects and can
+ * themselves be used as the target in a {@code synchronized} statement.
+ * Acquiring the
+ * monitor lock of a {@code Lock} instance has no specified relationship
+ * with invoking any of the {@link #lock} methods of that instance.
+ * It is recommended that to avoid confusion you never use {@code Lock}
+ * instances in this way, except within their own implementation.
+ *
+ * <p>Except where noted, passing a {@code null} value for any
+ * parameter will result in a {@link NullPointerException} being
+ * thrown.
+ *
+ * <h3>Memory Synchronization</h3>
+ *
+ * <p>All {@code Lock} implementations <em>must</em> enforce the same
+ * memory synchronization semantics as provided by the built-in monitor
+ * lock, as described in <a href="http://java.sun.com/docs/books/jls/">
+ * The Java Language Specification, Third Edition (17.4 Memory Model)</a>:
+ * <ul>
+ * <li>A successful {@code lock} operation has the same memory
+ * synchronization effects as a successful <em>Lock</em> action.
+ * <li>A successful {@code unlock} operation has the same
+ * memory synchronization effects as a successful <em>Unlock</em> action.
+ * </ul>
+ *
+ * Unsuccessful locking and unlocking operations, and reentrant
+ * locking/unlocking operations, do not require any memory
+ * synchronization effects.
+ *
+ * <h3>Implementation Considerations</h3>
+ *
+ * <p> The three forms of lock acquisition (interruptible,
+ * non-interruptible, and timed) may differ in their performance
+ * characteristics, ordering guarantees, or other implementation
+ * qualities. Further, the ability to interrupt the <em>ongoing</em>
+ * acquisition of a lock may not be available in a given {@code Lock}
+ * class. Consequently, an implementation is not required to define
+ * exactly the same guarantees or semantics for all three forms of
+ * lock acquisition, nor is it required to support interruption of an
+ * ongoing lock acquisition. An implementation is required to clearly
+ * document the semantics and guarantees provided by each of the
+ * locking methods. It must also obey the interruption semantics as
+ * defined in this interface, to the extent that interruption of lock
+ * acquisition is supported: which is either totally, or only on
+ * method entry.
+ *
+ * <p>As interruption generally implies cancellation, and checks for
+ * interruption are often infrequent, an implementation can favor responding
+ * to an interrupt over normal method return. This is true even if it can be
+ * shown that the interrupt occurred after another action may have unblocked
+ * the thread. An implementation should document this behavior.
+ *
+ * @see ReentrantLock
+ * @see Condition
+ * @see ReadWriteLock
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface Lock {
+
+ /**
+ * Acquires the lock.
+ *
+ * <p>If the lock is not available then the current thread becomes
+ * disabled for thread scheduling purposes and lies dormant until the
+ * lock has been acquired.
+ *
+ * <p><b>Implementation Considerations</b>
+ *
+ * <p>A {@code Lock} implementation may be able to detect erroneous use
+ * of the lock, such as an invocation that would cause deadlock, and
+ * may throw an (unchecked) exception in such circumstances. The
+ * circumstances and the exception type must be documented by that
+ * {@code Lock} implementation.
+ */
+ void lock();
+
+ /**
+ * Acquires the lock unless the current thread is
+ * {@linkplain Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the lock if it is available and returns immediately.
+ *
+ * <p>If the lock is not available then the current thread becomes
+ * disabled for thread scheduling purposes and lies dormant until
+ * one of two things happens:
+ *
+ * <ul>
+ * <li>The lock is acquired by the current thread; or
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+ * current thread, and interruption of lock acquisition is supported.
+ * </ul>
+ *
+ * <p>If the current thread:
+ * <ul>
+ * <li>has its interrupted status set on entry to this method; or
+ * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the
+ * lock, and interruption of lock acquisition is supported,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p><b>Implementation Considerations</b>
+ *
+ * <p>The ability to interrupt a lock acquisition in some
+ * implementations may not be possible, and if possible may be an
+ * expensive operation. The programmer should be aware that this
+ * may be the case. An implementation should document when this is
+ * the case.
+ *
+ * <p>An implementation can favor responding to an interrupt over
+ * normal method return.
+ *
+ * <p>A {@code Lock} implementation may be able to detect
+ * erroneous use of the lock, such as an invocation that would
+ * cause deadlock, and may throw an (unchecked) exception in such
+ * circumstances. The circumstances and the exception type must
+ * be documented by that {@code Lock} implementation.
+ *
+ * @throws InterruptedException if the current thread is
+ * interrupted while acquiring the lock (and interruption
+ * of lock acquisition is supported).
+ */
+ void lockInterruptibly() throws InterruptedException;
+
+ /**
+ * Acquires the lock only if it is free at the time of invocation.
+ *
+ * <p>Acquires the lock if it is available and returns immediately
+ * with the value {@code true}.
+ * If the lock is not available then this method will return
+ * immediately with the value {@code false}.
+ *
+ * <p>A typical usage idiom for this method would be:
+ * <pre>
+ * Lock lock = ...;
+ * if (lock.tryLock()) {
+ * try {
+ * // manipulate protected state
+ * } finally {
+ * lock.unlock();
+ * }
+ * } else {
+ * // perform alternative actions
+ * }
+ * </pre>
+ * This usage ensures that the lock is unlocked if it was acquired, and
+ * doesn't try to unlock if the lock was not acquired.
+ *
+ * @return {@code true} if the lock was acquired and
+ * {@code false} otherwise
+ */
+ boolean tryLock();
+
+ /**
+ * Acquires the lock if it is free within the given waiting time and the
+ * current thread has not been {@linkplain Thread#interrupt interrupted}.
+ *
+ * <p>If the lock is available this method returns immediately
+ * with the value {@code true}.
+ * If the lock is not available then
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happens:
+ * <ul>
+ * <li>The lock is acquired by the current thread; or
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+ * current thread, and interruption of lock acquisition is supported; or
+ * <li>The specified waiting time elapses
+ * </ul>
+ *
+ * <p>If the lock is acquired then the value {@code true} is returned.
+ *
+ * <p>If the current thread:
+ * <ul>
+ * <li>has its interrupted status set on entry to this method; or
+ * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
+ * the lock, and interruption of lock acquisition is supported,
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p>If the specified waiting time elapses then the value {@code false}
+ * is returned.
+ * If the time is
+ * less than or equal to zero, the method will not wait at all.
+ *
+ * <p><b>Implementation Considerations</b>
+ *
+ * <p>The ability to interrupt a lock acquisition in some implementations
+ * may not be possible, and if possible may
+ * be an expensive operation.
+ * The programmer should be aware that this may be the case. An
+ * implementation should document when this is the case.
+ *
+ * <p>An implementation can favor responding to an interrupt over normal
+ * method return, or reporting a timeout.
+ *
+ * <p>A {@code Lock} implementation may be able to detect
+ * erroneous use of the lock, such as an invocation that would cause
+ * deadlock, and may throw an (unchecked) exception in such circumstances.
+ * The circumstances and the exception type must be documented by that
+ * {@code Lock} implementation.
+ *
+ * @param time the maximum time to wait for the lock
+ * @param unit the time unit of the {@code time} argument
+ * @return {@code true} if the lock was acquired and {@code false}
+ * if the waiting time elapsed before the lock was acquired
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * while acquiring the lock (and interruption of lock
+ * acquisition is supported)
+ */
+ boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
+
+ /**
+ * Releases the lock.
+ *
+ * <p><b>Implementation Considerations</b>
+ *
+ * <p>A {@code Lock} implementation will usually impose
+ * restrictions on which thread can release a lock (typically only the
+ * holder of the lock can release it) and may throw
+ * an (unchecked) exception if the restriction is violated.
+ * Any restrictions and the exception
+ * type must be documented by that {@code Lock} implementation.
+ */
+ void unlock();
+
+ /**
+ * Returns a new {@link Condition} instance that is bound to this
+ * {@code Lock} instance.
+ *
+ * <p>Before waiting on the condition the lock must be held by the
+ * current thread.
+ * A call to {@link Condition#await()} will atomically release the lock
+ * before waiting and re-acquire the lock before the wait returns.
+ *
+ * <p><b>Implementation Considerations</b>
+ *
+ * <p>The exact operation of the {@link Condition} instance depends on
+ * the {@code Lock} implementation and must be documented by that
+ * implementation.
+ *
+ * @return A new {@link Condition} instance for this {@code Lock} instance
+ * @throws UnsupportedOperationException if this {@code Lock}
+ * implementation does not support conditions
+ */
+ Condition newCondition();
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/LockSupport.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/LockSupport.java
new file mode 100644
index 000000000..28728ae2b
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/LockSupport.java
@@ -0,0 +1,352 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.concurrent.*;
+import sun.misc.Unsafe;
+
+
+/**
+ * Basic thread blocking primitives for creating locks and other
+ * synchronization classes.
+ *
+ * <p>This class associates, with each thread that uses it, a permit
+ * (in the sense of the {@link java.util.concurrent.Semaphore
+ * Semaphore} class). A call to {@code park} will return immediately
+ * if the permit is available, consuming it in the process; otherwise
+ * it <em>may</em> block. A call to {@code unpark} makes the permit
+ * available, if it was not already available. (Unlike with Semaphores
+ * though, permits do not accumulate. There is at most one.)
+ *
+ * <p>Methods {@code park} and {@code unpark} provide efficient
+ * means of blocking and unblocking threads that do not encounter the
+ * problems that cause the deprecated methods {@code Thread.suspend}
+ * and {@code Thread.resume} to be unusable for such purposes: Races
+ * between one thread invoking {@code park} and another thread trying
+ * to {@code unpark} it will preserve liveness, due to the
+ * permit. Additionally, {@code park} will return if the caller's
+ * thread was interrupted, and timeout versions are supported. The
+ * {@code park} method may also return at any other time, for "no
+ * reason", so in general must be invoked within a loop that rechecks
+ * conditions upon return. In this sense {@code park} serves as an
+ * optimization of a "busy wait" that does not waste as much time
+ * spinning, but must be paired with an {@code unpark} to be
+ * effective.
+ *
+ * <p>The three forms of {@code park} each also support a
+ * {@code blocker} object parameter. This object is recorded while
+ * the thread is blocked to permit monitoring and diagnostic tools to
+ * identify the reasons that threads are blocked. (Such tools may
+ * access blockers using method {@link #getBlocker}.) The use of these
+ * forms rather than the original forms without this parameter is
+ * strongly encouraged. The normal argument to supply as a
+ * {@code blocker} within a lock implementation is {@code this}.
+ *
+ * <p>These methods are designed to be used as tools for creating
+ * higher-level synchronization utilities, and are not in themselves
+ * useful for most concurrency control applications. The {@code park}
+ * method is designed for use only in constructions of the form:
+ * <pre>while (!canProceed()) { ... LockSupport.park(this); }</pre>
+ * where neither {@code canProceed} nor any other actions prior to the
+ * call to {@code park} entail locking or blocking. Because only one
+ * permit is associated with each thread, any intermediary uses of
+ * {@code park} could interfere with its intended effects.
+ *
+ * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
+ * non-reentrant lock class:
+ * <pre>{@code
+ * class FIFOMutex {
+ * private final AtomicBoolean locked = new AtomicBoolean(false);
+ * private final Queue<Thread> waiters
+ * = new ConcurrentLinkedQueue<Thread>();
+ *
+ * public void lock() {
+ * boolean wasInterrupted = false;
+ * Thread current = Thread.currentThread();
+ * waiters.add(current);
+ *
+ * // Block while not first in queue or cannot acquire lock
+ * while (waiters.peek() != current ||
+ * !locked.compareAndSet(false, true)) {
+ * LockSupport.park(this);
+ * if (Thread.interrupted()) // ignore interrupts while waiting
+ * wasInterrupted = true;
+ * }
+ *
+ * waiters.remove();
+ * if (wasInterrupted) // reassert interrupt status on exit
+ * current.interrupt();
+ * }
+ *
+ * public void unlock() {
+ * locked.set(false);
+ * LockSupport.unpark(waiters.peek());
+ * }
+ * }}</pre>
+ */
+
+public class LockSupport {
+ private LockSupport() {} // Cannot be instantiated.
+
+ // Hotspot implementation via intrinsics API
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+ private static final long parkBlockerOffset;
+
+ static {
+ try {
+ parkBlockerOffset = unsafe.objectFieldOffset
+ (java.lang.Thread.class.getDeclaredField("parkBlocker"));
+ } catch (Exception ex) { throw new Error(ex); }
+ }
+
+ private static void setBlocker(Thread t, Object arg) {
+ // Even though volatile, hotspot doesn't need a write barrier here.
+ unsafe.putObject(t, parkBlockerOffset, arg);
+ }
+
+ /**
+ * Makes available the permit for the given thread, if it
+ * was not already available. If the thread was blocked on
+ * {@code park} then it will unblock. Otherwise, its next call
+ * to {@code park} is guaranteed not to block. This operation
+ * is not guaranteed to have any effect at all if the given
+ * thread has not been started.
+ *
+ * @param thread the thread to unpark, or {@code null}, in which case
+ * this operation has no effect
+ */
+ public static void unpark(Thread thread) {
+ if (thread != null)
+ unsafe.unpark(thread);
+ }
+
+ /**
+ * Disables the current thread for thread scheduling purposes unless the
+ * permit is available.
+ *
+ * <p>If the permit is available then it is consumed and the call returns
+ * immediately; otherwise
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happens:
+ *
+ * <ul>
+ * <li>Some other thread invokes {@link #unpark unpark} with the
+ * current thread as the target; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread; or
+ *
+ * <li>The call spuriously (that is, for no reason) returns.
+ * </ul>
+ *
+ * <p>This method does <em>not</em> report which of these caused the
+ * method to return. Callers should re-check the conditions which caused
+ * the thread to park in the first place. Callers may also determine,
+ * for example, the interrupt status of the thread upon return.
+ *
+ * @param blocker the synchronization object responsible for this
+ * thread parking
+ * @since 1.6
+ */
+ public static void park(Object blocker) {
+ Thread t = Thread.currentThread();
+ setBlocker(t, blocker);
+ unsafe.park(false, 0L);
+ setBlocker(t, null);
+ }
+
+ /**
+ * Disables the current thread for thread scheduling purposes, for up to
+ * the specified waiting time, unless the permit is available.
+ *
+ * <p>If the permit is available then it is consumed and the call
+ * returns immediately; otherwise the current thread becomes disabled
+ * for thread scheduling purposes and lies dormant until one of four
+ * things happens:
+ *
+ * <ul>
+ * <li>Some other thread invokes {@link #unpark unpark} with the
+ * current thread as the target; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts} the current
+ * thread; or
+ *
+ * <li>The specified waiting time elapses; or
+ *
+ * <li>The call spuriously (that is, for no reason) returns.
+ * </ul>
+ *
+ * <p>This method does <em>not</em> report which of these caused the
+ * method to return. Callers should re-check the conditions which caused
+ * the thread to park in the first place. Callers may also determine,
+ * for example, the interrupt status of the thread, or the elapsed time
+ * upon return.
+ *
+ * @param blocker the synchronization object responsible for this
+ * thread parking
+ * @param nanos the maximum number of nanoseconds to wait
+ * @since 1.6
+ */
+ public static void parkNanos(Object blocker, long nanos) {
+ if (nanos > 0) {
+ Thread t = Thread.currentThread();
+ setBlocker(t, blocker);
+ unsafe.park(false, nanos);
+ setBlocker(t, null);
+ }
+ }
+
+ /**
+ * Disables the current thread for thread scheduling purposes, until
+ * the specified deadline, unless the permit is available.
+ *
+ * <p>If the permit is available then it is consumed and the call
+ * returns immediately; otherwise the current thread becomes disabled
+ * for thread scheduling purposes and lies dormant until one of four
+ * things happens:
+ *
+ * <ul>
+ * <li>Some other thread invokes {@link #unpark unpark} with the
+ * current thread as the target; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+ * current thread; or
+ *
+ * <li>The specified deadline passes; or
+ *
+ * <li>The call spuriously (that is, for no reason) returns.
+ * </ul>
+ *
+ * <p>This method does <em>not</em> report which of these caused the
+ * method to return. Callers should re-check the conditions which caused
+ * the thread to park in the first place. Callers may also determine,
+ * for example, the interrupt status of the thread, or the current time
+ * upon return.
+ *
+ * @param blocker the synchronization object responsible for this
+ * thread parking
+ * @param deadline the absolute time, in milliseconds from the Epoch,
+ * to wait until
+ * @since 1.6
+ */
+ public static void parkUntil(Object blocker, long deadline) {
+ Thread t = Thread.currentThread();
+ setBlocker(t, blocker);
+ unsafe.park(true, deadline);
+ setBlocker(t, null);
+ }
+
+ /**
+ * Returns the blocker object supplied to the most recent
+ * invocation of a park method that has not yet unblocked, or null
+ * if not blocked. The value returned is just a momentary
+ * snapshot -- the thread may have since unblocked or blocked on a
+ * different blocker object.
+ *
+ * @return the blocker
+ * @since 1.6
+ */
+ public static Object getBlocker(Thread t) {
+ return unsafe.getObjectVolatile(t, parkBlockerOffset);
+ }
+
+ /**
+ * Disables the current thread for thread scheduling purposes unless the
+ * permit is available.
+ *
+ * <p>If the permit is available then it is consumed and the call
+ * returns immediately; otherwise the current thread becomes disabled
+ * for thread scheduling purposes and lies dormant until one of three
+ * things happens:
+ *
+ * <ul>
+ *
+ * <li>Some other thread invokes {@link #unpark unpark} with the
+ * current thread as the target; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread; or
+ *
+ * <li>The call spuriously (that is, for no reason) returns.
+ * </ul>
+ *
+ * <p>This method does <em>not</em> report which of these caused the
+ * method to return. Callers should re-check the conditions which caused
+ * the thread to park in the first place. Callers may also determine,
+ * for example, the interrupt status of the thread upon return.
+ */
+ public static void park() {
+ unsafe.park(false, 0L);
+ }
+
+ /**
+ * Disables the current thread for thread scheduling purposes, for up to
+ * the specified waiting time, unless the permit is available.
+ *
+ * <p>If the permit is available then it is consumed and the call
+ * returns immediately; otherwise the current thread becomes disabled
+ * for thread scheduling purposes and lies dormant until one of four
+ * things happens:
+ *
+ * <ul>
+ * <li>Some other thread invokes {@link #unpark unpark} with the
+ * current thread as the target; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread; or
+ *
+ * <li>The specified waiting time elapses; or
+ *
+ * <li>The call spuriously (that is, for no reason) returns.
+ * </ul>
+ *
+ * <p>This method does <em>not</em> report which of these caused the
+ * method to return. Callers should re-check the conditions which caused
+ * the thread to park in the first place. Callers may also determine,
+ * for example, the interrupt status of the thread, or the elapsed time
+ * upon return.
+ *
+ * @param nanos the maximum number of nanoseconds to wait
+ */
+ public static void parkNanos(long nanos) {
+ if (nanos > 0)
+ unsafe.park(false, nanos);
+ }
+
+ /**
+ * Disables the current thread for thread scheduling purposes, until
+ * the specified deadline, unless the permit is available.
+ *
+ * <p>If the permit is available then it is consumed and the call
+ * returns immediately; otherwise the current thread becomes disabled
+ * for thread scheduling purposes and lies dormant until one of four
+ * things happens:
+ *
+ * <ul>
+ * <li>Some other thread invokes {@link #unpark unpark} with the
+ * current thread as the target; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread; or
+ *
+ * <li>The specified deadline passes; or
+ *
+ * <li>The call spuriously (that is, for no reason) returns.
+ * </ul>
+ *
+ * <p>This method does <em>not</em> report which of these caused the
+ * method to return. Callers should re-check the conditions which caused
+ * the thread to park in the first place. Callers may also determine,
+ * for example, the interrupt status of the thread, or the current time
+ * upon return.
+ *
+ * @param deadline the absolute time, in milliseconds from the Epoch,
+ * to wait until
+ */
+ public static void parkUntil(long deadline) {
+ unsafe.park(true, deadline);
+ }
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReadWriteLock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReadWriteLock.java
new file mode 100644
index 000000000..484f68d15
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReadWriteLock.java
@@ -0,0 +1,104 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+
+/**
+ * A <tt>ReadWriteLock</tt> maintains a pair of associated {@link
+ * Lock locks}, one for read-only operations and one for writing.
+ * The {@link #readLock read lock} may be held simultaneously by
+ * multiple reader threads, so long as there are no writers. The
+ * {@link #writeLock write lock} is exclusive.
+ *
+ * <p>All <tt>ReadWriteLock</tt> implementations must guarantee that
+ * the memory synchronization effects of <tt>writeLock</tt> operations
+ * (as specified in the {@link Lock} interface) also hold with respect
+ * to the associated <tt>readLock</tt>. That is, a thread successfully
+ * acquiring the read lock will see all updates made upon previous
+ * release of the write lock.
+ *
+ * <p>A read-write lock allows for a greater level of concurrency in
+ * accessing shared data than that permitted by a mutual exclusion lock.
+ * It exploits the fact that while only a single thread at a time (a
+ * <em>writer</em> thread) can modify the shared data, in many cases any
+ * number of threads can concurrently read the data (hence <em>reader</em>
+ * threads).
+ * In theory, the increase in concurrency permitted by the use of a read-write
+ * lock will lead to performance improvements over the use of a mutual
+ * exclusion lock. In practice this increase in concurrency will only be fully
+ * realized on a multi-processor, and then only if the access patterns for
+ * the shared data are suitable.
+ *
+ * <p>Whether or not a read-write lock will improve performance over the use
+ * of a mutual exclusion lock depends on the frequency that the data is
+ * read compared to being modified, the duration of the read and write
+ * operations, and the contention for the data - that is, the number of
+ * threads that will try to read or write the data at the same time.
+ * For example, a collection that is initially populated with data and
+ * thereafter infrequently modified, while being frequently searched
+ * (such as a directory of some kind) is an ideal candidate for the use of
+ * a read-write lock. However, if updates become frequent then the data
+ * spends most of its time being exclusively locked and there is little, if any
+ * increase in concurrency. Further, if the read operations are too short
+ * the overhead of the read-write lock implementation (which is inherently
+ * more complex than a mutual exclusion lock) can dominate the execution
+ * cost, particularly as many read-write lock implementations still serialize
+ * all threads through a small section of code. Ultimately, only profiling
+ * and measurement will establish whether the use of a read-write lock is
+ * suitable for your application.
+ *
+ *
+ * <p>Although the basic operation of a read-write lock is straight-forward,
+ * there are many policy decisions that an implementation must make, which
+ * may affect the effectiveness of the read-write lock in a given application.
+ * Examples of these policies include:
+ * <ul>
+ * <li>Determining whether to grant the read lock or the write lock, when
+ * both readers and writers are waiting, at the time that a writer releases
+ * the write lock. Writer preference is common, as writes are expected to be
+ * short and infrequent. Reader preference is less common as it can lead to
+ * lengthy delays for a write if the readers are frequent and long-lived as
+ * expected. Fair, or &quot;in-order&quot; implementations are also possible.
+ *
+ * <li>Determining whether readers that request the read lock while a
+ * reader is active and a writer is waiting, are granted the read lock.
+ * Preference to the reader can delay the writer indefinitely, while
+ * preference to the writer can reduce the potential for concurrency.
+ *
+ * <li>Determining whether the locks are reentrant: can a thread with the
+ * write lock reacquire it? Can it acquire a read lock while holding the
+ * write lock? Is the read lock itself reentrant?
+ *
+ * <li>Can the write lock be downgraded to a read lock without allowing
+ * an intervening writer? Can a read lock be upgraded to a write lock,
+ * in preference to other waiting readers or writers?
+ *
+ * </ul>
+ * You should consider all of these things when evaluating the suitability
+ * of a given implementation for your application.
+ *
+ * @see ReentrantReadWriteLock
+ * @see Lock
+ * @see ReentrantLock
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface ReadWriteLock {
+ /**
+ * Returns the lock used for reading.
+ *
+ * @return the lock used for reading.
+ */
+ Lock readLock();
+
+ /**
+ * Returns the lock used for writing.
+ *
+ * @return the lock used for writing.
+ */
+ Lock writeLock();
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantLock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantLock.java
new file mode 100644
index 000000000..4a2fc175c
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantLock.java
@@ -0,0 +1,740 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+/**
+ * A reentrant mutual exclusion {@link Lock} with the same basic
+ * behavior and semantics as the implicit monitor lock accessed using
+ * {@code synchronized} methods and statements, but with extended
+ * capabilities.
+ *
+ * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
+ * successfully locking, but not yet unlocking it. A thread invoking
+ * {@code lock} will return, successfully acquiring the lock, when
+ * the lock is not owned by another thread. The method will return
+ * immediately if the current thread already owns the lock. This can
+ * be checked using methods {@link #isHeldByCurrentThread}, and {@link
+ * #getHoldCount}.
+ *
+ * <p>The constructor for this class accepts an optional
+ * <em>fairness</em> parameter. When set {@code true}, under
+ * contention, locks favor granting access to the longest-waiting
+ * thread. Otherwise this lock does not guarantee any particular
+ * access order. Programs using fair locks accessed by many threads
+ * may display lower overall throughput (i.e., are slower; often much
+ * slower) than those using the default setting, but have smaller
+ * variances in times to obtain locks and guarantee lack of
+ * starvation. Note however, that fairness of locks does not guarantee
+ * fairness of thread scheduling. Thus, one of many threads using a
+ * fair lock may obtain it multiple times in succession while other
+ * active threads are not progressing and not currently holding the
+ * lock.
+ * Also note that the untimed {@link #tryLock() tryLock} method does not
+ * honor the fairness setting. It will succeed if the lock
+ * is available even if other threads are waiting.
+ *
+ * <p>It is recommended practice to <em>always</em> immediately
+ * follow a call to {@code lock} with a {@code try} block, most
+ * typically in a before/after construction such as:
+ *
+ * <pre>
+ * class X {
+ * private final ReentrantLock lock = new ReentrantLock();
+ * // ...
+ *
+ * public void m() {
+ * lock.lock(); // block until condition holds
+ * try {
+ * // ... method body
+ * } finally {
+ * lock.unlock()
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * <p>In addition to implementing the {@link Lock} interface, this
+ * class defines methods {@code isLocked} and
+ * {@code getLockQueueLength}, as well as some associated
+ * {@code protected} access methods that may be useful for
+ * instrumentation and monitoring.
+ *
+ * <p>Serialization of this class behaves in the same way as built-in
+ * locks: a deserialized lock is in the unlocked state, regardless of
+ * its state when serialized.
+ *
+ * <p>This lock supports a maximum of 2147483647 recursive locks by
+ * the same thread. Attempts to exceed this limit result in
+ * {@link Error} throws from locking methods.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public class ReentrantLock implements Lock, java.io.Serializable {
+ private static final long serialVersionUID = 7373984872572414699L;
+ /** Synchronizer providing all implementation mechanics */
+ private final Sync sync;
+
+ /**
+ * Base of synchronization control for this lock. Subclassed
+ * into fair and nonfair versions below. Uses AQS state to
+ * represent the number of holds on the lock.
+ */
+ static abstract class Sync extends AbstractQueuedSynchronizer {
+ private static final long serialVersionUID = -5179523762034025860L;
+
+ /**
+ * Performs {@link Lock#lock}. The main reason for subclassing
+ * is to allow fast path for nonfair version.
+ */
+ abstract void lock();
+
+ /**
+ * Performs non-fair tryLock. tryAcquire is
+ * implemented in subclasses, but both need nonfair
+ * try for trylock method.
+ */
+ final boolean nonfairTryAcquire(int acquires) {
+ final Thread current = Thread.currentThread();
+ int c = getState();
+ if (c == 0) {
+ if (compareAndSetState(0, acquires)) {
+ setExclusiveOwnerThread(current);
+ return true;
+ }
+ }
+ else if (current == getExclusiveOwnerThread()) {
+ int nextc = c + acquires;
+ if (nextc < 0) // overflow
+ throw new Error("Maximum lock count exceeded");
+ setState(nextc);
+ return true;
+ }
+ return false;
+ }
+
+ protected final boolean tryRelease(int releases) {
+ int c = getState() - releases;
+ if (Thread.currentThread() != getExclusiveOwnerThread())
+ throw new IllegalMonitorStateException();
+ boolean free = false;
+ if (c == 0) {
+ free = true;
+ setExclusiveOwnerThread(null);
+ }
+ setState(c);
+ return free;
+ }
+
+ protected final boolean isHeldExclusively() {
+ // While we must in general read state before owner,
+ // we don't need to do so to check if current thread is owner
+ return getExclusiveOwnerThread() == Thread.currentThread();
+ }
+
+ final ConditionObject newCondition() {
+ return new ConditionObject();
+ }
+
+ // Methods relayed from outer class
+
+ final Thread getOwner() {
+ return getState() == 0 ? null : getExclusiveOwnerThread();
+ }
+
+ final int getHoldCount() {
+ return isHeldExclusively() ? getState() : 0;
+ }
+
+ final boolean isLocked() {
+ return getState() != 0;
+ }
+
+ /**
+ * Reconstitutes this lock instance from a stream.
+ * @param s the stream
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ setState(0); // reset to unlocked state
+ }
+ }
+
+ /**
+ * Sync object for non-fair locks
+ */
+ final static class NonfairSync extends Sync {
+ private static final long serialVersionUID = 7316153563782823691L;
+
+ /**
+ * Performs lock. Try immediate barge, backing up to normal
+ * acquire on failure.
+ */
+ final void lock() {
+ if (compareAndSetState(0, 1))
+ setExclusiveOwnerThread(Thread.currentThread());
+ else
+ acquire(1);
+ }
+
+ protected final boolean tryAcquire(int acquires) {
+ return nonfairTryAcquire(acquires);
+ }
+ }
+
+ /**
+ * Sync object for fair locks
+ */
+ final static class FairSync extends Sync {
+ private static final long serialVersionUID = -3000897897090466540L;
+
+ final void lock() {
+ acquire(1);
+ }
+
+ /**
+ * Fair version of tryAcquire. Don't grant access unless
+ * recursive call or no waiters or is first.
+ */
+ protected final boolean tryAcquire(int acquires) {
+ final Thread current = Thread.currentThread();
+ int c = getState();
+ if (c == 0) {
+ if (isFirst(current) &&
+ compareAndSetState(0, acquires)) {
+ setExclusiveOwnerThread(current);
+ return true;
+ }
+ }
+ else if (current == getExclusiveOwnerThread()) {
+ int nextc = c + acquires;
+ if (nextc < 0)
+ throw new Error("Maximum lock count exceeded");
+ setState(nextc);
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Creates an instance of {@code ReentrantLock}.
+ * This is equivalent to using {@code ReentrantLock(false)}.
+ */
+ public ReentrantLock() {
+ sync = new NonfairSync();
+ }
+
+ /**
+ * Creates an instance of {@code ReentrantLock} with the
+ * given fairness policy.
+ *
+ * @param fair {@code true} if this lock should use a fair ordering policy
+ */
+ public ReentrantLock(boolean fair) {
+ sync = (fair)? new FairSync() : new NonfairSync();
+ }
+
+ /**
+ * Acquires the lock.
+ *
+ * <p>Acquires the lock if it is not held by another thread and returns
+ * immediately, setting the lock hold count to one.
+ *
+ * <p>If the current thread already holds the lock then the hold
+ * count is incremented by one and the method returns immediately.
+ *
+ * <p>If the lock is held by another thread then the
+ * current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until the lock has been acquired,
+ * at which time the lock hold count is set to one.
+ */
+ public void lock() {
+ sync.lock();
+ }
+
+ /**
+ * Acquires the lock unless the current thread is
+ * {@linkplain Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the lock if it is not held by another thread and returns
+ * immediately, setting the lock hold count to one.
+ *
+ * <p>If the current thread already holds this lock then the hold count
+ * is incremented by one and the method returns immediately.
+ *
+ * <p>If the lock is held by another thread then the
+ * current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of two things happens:
+ *
+ * <ul>
+ *
+ * <li>The lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+ * current thread.
+ *
+ * </ul>
+ *
+ * <p>If the lock is acquired by the current thread then the lock hold
+ * count is set to one.
+ *
+ * <p>If the current thread:
+ *
+ * <ul>
+ *
+ * <li>has its interrupted status set on entry to this method; or
+ *
+ * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
+ * the lock,
+ *
+ * </ul>
+ *
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p>In this implementation, as this method is an explicit
+ * interruption point, preference is given to responding to the
+ * interrupt over normal or reentrant acquisition of the lock.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public void lockInterruptibly() throws InterruptedException {
+ sync.acquireInterruptibly(1);
+ }
+
+ /**
+ * Acquires the lock only if it is not held by another thread at the time
+ * of invocation.
+ *
+ * <p>Acquires the lock if it is not held by another thread and
+ * returns immediately with the value {@code true}, setting the
+ * lock hold count to one. Even when this lock has been set to use a
+ * fair ordering policy, a call to {@code tryLock()} <em>will</em>
+ * immediately acquire the lock if it is available, whether or not
+ * other threads are currently waiting for the lock.
+ * This &quot;barging&quot; behavior can be useful in certain
+ * circumstances, even though it breaks fairness. If you want to honor
+ * the fairness setting for this lock, then use
+ * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
+ * which is almost equivalent (it also detects interruption).
+ *
+ * <p> If the current thread already holds this lock then the hold
+ * count is incremented by one and the method returns {@code true}.
+ *
+ * <p>If the lock is held by another thread then this method will return
+ * immediately with the value {@code false}.
+ *
+ * @return {@code true} if the lock was free and was acquired by the
+ * current thread, or the lock was already held by the current
+ * thread; and {@code false} otherwise
+ */
+ public boolean tryLock() {
+ return sync.nonfairTryAcquire(1);
+ }
+
+ /**
+ * Acquires the lock if it is not held by another thread within the given
+ * waiting time and the current thread has not been
+ * {@linkplain Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the lock if it is not held by another thread and returns
+ * immediately with the value {@code true}, setting the lock hold count
+ * to one. If this lock has been set to use a fair ordering policy then
+ * an available lock <em>will not</em> be acquired if any other threads
+ * are waiting for the lock. This is in contrast to the {@link #tryLock()}
+ * method. If you want a timed {@code tryLock} that does permit barging on
+ * a fair lock then combine the timed and un-timed forms together:
+ *
+ * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
+ * </pre>
+ *
+ * <p>If the current thread
+ * already holds this lock then the hold count is incremented by one and
+ * the method returns {@code true}.
+ *
+ * <p>If the lock is held by another thread then the
+ * current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happens:
+ *
+ * <ul>
+ *
+ * <li>The lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread; or
+ *
+ * <li>The specified waiting time elapses
+ *
+ * </ul>
+ *
+ * <p>If the lock is acquired then the value {@code true} is returned and
+ * the lock hold count is set to one.
+ *
+ * <p>If the current thread:
+ *
+ * <ul>
+ *
+ * <li>has its interrupted status set on entry to this method; or
+ *
+ * <li>is {@linkplain Thread#interrupt interrupted} while
+ * acquiring the lock,
+ *
+ * </ul>
+ * then {@link InterruptedException} is thrown and the current thread's
+ * interrupted status is cleared.
+ *
+ * <p>If the specified waiting time elapses then the value {@code false}
+ * is returned. If the time is less than or equal to zero, the method
+ * will not wait at all.
+ *
+ * <p>In this implementation, as this method is an explicit
+ * interruption point, preference is given to responding to the
+ * interrupt over normal or reentrant acquisition of the lock, and
+ * over reporting the elapse of the waiting time.
+ *
+ * @param timeout the time to wait for the lock
+ * @param unit the time unit of the timeout argument
+ * @return {@code true} if the lock was free and was acquired by the
+ * current thread, or the lock was already held by the current
+ * thread; and {@code false} if the waiting time elapsed before
+ * the lock could be acquired
+ * @throws InterruptedException if the current thread is interrupted
+ * @throws NullPointerException if the time unit is null
+ *
+ */
+ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ return sync.tryAcquireNanos(1, unit.toNanos(timeout));
+ }
+
+ /**
+ * Attempts to release this lock.
+ *
+ * <p>If the current thread is the holder of this lock then the hold
+ * count is decremented. If the hold count is now zero then the lock
+ * is released. If the current thread is not the holder of this
+ * lock then {@link IllegalMonitorStateException} is thrown.
+ *
+ * @throws IllegalMonitorStateException if the current thread does not
+ * hold this lock
+ */
+ public void unlock() {
+ sync.release(1);
+ }
+
+ /**
+ * Returns a {@link Condition} instance for use with this
+ * {@link Lock} instance.
+ *
+ * <p>The returned {@link Condition} instance supports the same
+ * usages as do the {@link Object} monitor methods ({@link
+ * Object#wait() wait}, {@link Object#notify notify}, and {@link
+ * Object#notifyAll notifyAll}) when used with the built-in
+ * monitor lock.
+ *
+ * <ul>
+ *
+ * <li>If this lock is not held when any of the {@link Condition}
+ * {@linkplain Condition#await() waiting} or {@linkplain
+ * Condition#signal signalling} methods are called, then an {@link
+ * IllegalMonitorStateException} is thrown.
+ *
+ * <li>When the condition {@linkplain Condition#await() waiting}
+ * methods are called the lock is released and, before they
+ * return, the lock is reacquired and the lock hold count restored
+ * to what it was when the method was called.
+ *
+ * <li>If a thread is {@linkplain Thread#interrupt interrupted}
+ * while waiting then the wait will terminate, an {@link
+ * InterruptedException} will be thrown, and the thread's
+ * interrupted status will be cleared.
+ *
+ * <li> Waiting threads are signalled in FIFO order.
+ *
+ * <li>The ordering of lock reacquisition for threads returning
+ * from waiting methods is the same as for threads initially
+ * acquiring the lock, which is in the default case not specified,
+ * but for <em>fair</em> locks favors those threads that have been
+ * waiting the longest.
+ *
+ * </ul>
+ *
+ * @return the Condition object
+ */
+ public Condition newCondition() {
+ return sync.newCondition();
+ }
+
+ /**
+ * Queries the number of holds on this lock by the current thread.
+ *
+ * <p>A thread has a hold on a lock for each lock action that is not
+ * matched by an unlock action.
+ *
+ * <p>The hold count information is typically only used for testing and
+ * debugging purposes. For example, if a certain section of code should
+ * not be entered with the lock already held then we can assert that
+ * fact:
+ *
+ * <pre>
+ * class X {
+ * ReentrantLock lock = new ReentrantLock();
+ * // ...
+ * public void m() {
+ * assert lock.getHoldCount() == 0;
+ * lock.lock();
+ * try {
+ * // ... method body
+ * } finally {
+ * lock.unlock();
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * @return the number of holds on this lock by the current thread,
+ * or zero if this lock is not held by the current thread
+ */
+ public int getHoldCount() {
+ return sync.getHoldCount();
+ }
+
+ /**
+ * Queries if this lock is held by the current thread.
+ *
+ * <p>Analogous to the {@link Thread#holdsLock} method for built-in
+ * monitor locks, this method is typically used for debugging and
+ * testing. For example, a method that should only be called while
+ * a lock is held can assert that this is the case:
+ *
+ * <pre>
+ * class X {
+ * ReentrantLock lock = new ReentrantLock();
+ * // ...
+ *
+ * public void m() {
+ * assert lock.isHeldByCurrentThread();
+ * // ... method body
+ * }
+ * }
+ * </pre>
+ *
+ * <p>It can also be used to ensure that a reentrant lock is used
+ * in a non-reentrant manner, for example:
+ *
+ * <pre>
+ * class X {
+ * ReentrantLock lock = new ReentrantLock();
+ * // ...
+ *
+ * public void m() {
+ * assert !lock.isHeldByCurrentThread();
+ * lock.lock();
+ * try {
+ * // ... method body
+ * } finally {
+ * lock.unlock();
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * @return {@code true} if current thread holds this lock and
+ * {@code false} otherwise
+ */
+ public boolean isHeldByCurrentThread() {
+ return sync.isHeldExclusively();
+ }
+
+ /**
+ * Queries if this lock is held by any thread. This method is
+ * designed for use in monitoring of the system state,
+ * not for synchronization control.
+ *
+ * @return {@code true} if any thread holds this lock and
+ * {@code false} otherwise
+ */
+ public boolean isLocked() {
+ return sync.isLocked();
+ }
+
+ /**
+ * Returns {@code true} if this lock has fairness set true.
+ *
+ * @return {@code true} if this lock has fairness set true
+ */
+ public final boolean isFair() {
+ return sync instanceof FairSync;
+ }
+
+ /**
+ * Returns the thread that currently owns this lock, or
+ * {@code null} if not owned. When this method is called by a
+ * thread that is not the owner, the return value reflects a
+ * best-effort approximation of current lock status. For example,
+ * the owner may be momentarily {@code null} even if there are
+ * threads trying to acquire the lock but have not yet done so.
+ * This method is designed to facilitate construction of
+ * subclasses that provide more extensive lock monitoring
+ * facilities.
+ *
+ * @return the owner, or {@code null} if not owned
+ */
+ protected Thread getOwner() {
+ return sync.getOwner();
+ }
+
+ /**
+ * Queries whether any threads are waiting to acquire this lock. Note that
+ * because cancellations may occur at any time, a {@code true}
+ * return does not guarantee that any other thread will ever
+ * acquire this lock. This method is designed primarily for use in
+ * monitoring of the system state.
+ *
+ * @return {@code true} if there may be other threads waiting to
+ * acquire the lock
+ */
+ public final boolean hasQueuedThreads() {
+ return sync.hasQueuedThreads();
+ }
+
+
+ /**
+ * Queries whether the given thread is waiting to acquire this
+ * lock. Note that because cancellations may occur at any time, a
+ * {@code true} return does not guarantee that this thread
+ * will ever acquire this lock. This method is designed primarily for use
+ * in monitoring of the system state.
+ *
+ * @param thread the thread
+ * @return {@code true} if the given thread is queued waiting for this lock
+ * @throws NullPointerException if the thread is null
+ */
+ public final boolean hasQueuedThread(Thread thread) {
+ return sync.isQueued(thread);
+ }
+
+
+ /**
+ * Returns an estimate of the number of threads waiting to
+ * acquire this lock. The value is only an estimate because the number of
+ * threads may change dynamically while this method traverses
+ * internal data structures. This method is designed for use in
+ * monitoring of the system state, not for synchronization
+ * control.
+ *
+ * @return the estimated number of threads waiting for this lock
+ */
+ public final int getQueueLength() {
+ return sync.getQueueLength();
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire this lock. Because the actual set of threads may change
+ * dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive monitoring facilities.
+ *
+ * @return the collection of threads
+ */
+ protected Collection<Thread> getQueuedThreads() {
+ return sync.getQueuedThreads();
+ }
+
+ /**
+ * Queries whether any threads are waiting on the given condition
+ * associated with this lock. Note that because timeouts and
+ * interrupts may occur at any time, a {@code true} return does
+ * not guarantee that a future {@code signal} will awaken any
+ * threads. This method is designed primarily for use in
+ * monitoring of the system state.
+ *
+ * @param condition the condition
+ * @return {@code true} if there are any waiting threads
+ * @throws IllegalMonitorStateException if this lock is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if the condition is null
+ */
+ public boolean hasWaiters(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting on the
+ * given condition associated with this lock. Note that because
+ * timeouts and interrupts may occur at any time, the estimate
+ * serves only as an upper bound on the actual number of waiters.
+ * This method is designed for use in monitoring of the system
+ * state, not for synchronization control.
+ *
+ * @param condition the condition
+ * @return the estimated number of waiting threads
+ * @throws IllegalMonitorStateException if this lock is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if the condition is null
+ */
+ public int getWaitQueueLength(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns a collection containing those threads that may be
+ * waiting on the given condition associated with this lock.
+ * Because the actual set of threads may change dynamically while
+ * constructing this result, the returned collection is only a
+ * best-effort estimate. The elements of the returned collection
+ * are in no particular order. This method is designed to
+ * facilitate construction of subclasses that provide more
+ * extensive condition monitoring facilities.
+ *
+ * @param condition the condition
+ * @return the collection of threads
+ * @throws IllegalMonitorStateException if this lock is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if the condition is null
+ */
+ protected Collection<Thread> getWaitingThreads(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns a string identifying this lock, as well as its lock state.
+ * The state, in brackets, includes either the String {@code "Unlocked"}
+ * or the String {@code "Locked by"} followed by the
+ * {@linkplain Thread#getName name} of the owning thread.
+ *
+ * @return a string identifying this lock, as well as its lock state
+ */
+ public String toString() {
+ Thread o = sync.getOwner();
+ return super.toString() + ((o == null) ?
+ "[Unlocked]" :
+ "[Locked by thread " + o.getName() + "]");
+ }
+}
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantReadWriteLock.java b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantReadWriteLock.java
new file mode 100644
index 000000000..a6eadff5b
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/locks/ReentrantReadWriteLock.java
@@ -0,0 +1,1346 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+import java.util.*;
+
+/**
+ * An implementation of {@link ReadWriteLock} supporting similar
+ * semantics to {@link ReentrantLock}.
+ * <p>This class has the following properties:
+ *
+ * <ul>
+ * <li><b>Acquisition order</b>
+ *
+ * <p> This class does not impose a reader or writer preference
+ * ordering for lock access. However, it does support an optional
+ * <em>fairness</em> policy.
+ *
+ * <dl>
+ * <dt><b><i>Non-fair mode (default)</i></b>
+ * <dd>When constructed as non-fair (the default), the order of entry
+ * to the read and write lock is unspecified, subject to reentrancy
+ * constraints. A nonfair lock that is continously contended may
+ * indefinitely postpone one or more reader or writer threads, but
+ * will normally have higher throughput than a fair lock.
+ * <p>
+ *
+ * <dt><b><i>Fair mode</i></b>
+ * <dd> When constructed as fair, threads contend for entry using an
+ * approximately arrival-order policy. When the currently held lock
+ * is released either the longest-waiting single writer thread will
+ * be assigned the write lock, or if there is a group of reader threads
+ * waiting longer than all waiting writer threads, that group will be
+ * assigned the read lock.
+ *
+ * <p>A thread that tries to acquire a fair read lock (non-reentrantly)
+ * will block if either the write lock is held, or there is a waiting
+ * writer thread. The thread will not acquire the read lock until
+ * after the oldest currently waiting writer thread has acquired and
+ * released the write lock. Of course, if a waiting writer abandons
+ * its wait, leaving one or more reader threads as the longest waiters
+ * in the queue with the write lock free, then those readers will be
+ * assigned the read lock.
+ *
+ * <p>A thread that tries to acquire a fair write lock (non-reentrantly)
+ * will block unless both the read lock and write lock are free (which
+ * implies there are no waiting threads). (Note that the non-blocking
+ * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
+ * do not honor this fair setting and will acquire the lock if it is
+ * possible, regardless of waiting threads.)
+ * <p>
+ * </dl>
+ *
+ * <li><b>Reentrancy</b>
+ *
+ * <p>This lock allows both readers and writers to reacquire read or
+ * write locks in the style of a {@link ReentrantLock}. Non-reentrant
+ * readers are not allowed until all write locks held by the writing
+ * thread have been released.
+ *
+ * <p>Additionally, a writer can acquire the read lock, but not
+ * vice-versa. Among other applications, reentrancy can be useful
+ * when write locks are held during calls or callbacks to methods that
+ * perform reads under read locks. If a reader tries to acquire the
+ * write lock it will never succeed.
+ *
+ * <li><b>Lock downgrading</b>
+ * <p>Reentrancy also allows downgrading from the write lock to a read lock,
+ * by acquiring the write lock, then the read lock and then releasing the
+ * write lock. However, upgrading from a read lock to the write lock is
+ * <b>not</b> possible.
+ *
+ * <li><b>Interruption of lock acquisition</b>
+ * <p>The read lock and write lock both support interruption during lock
+ * acquisition.
+ *
+ * <li><b>{@link Condition} support</b>
+ * <p>The write lock provides a {@link Condition} implementation that
+ * behaves in the same way, with respect to the write lock, as the
+ * {@link Condition} implementation provided by
+ * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
+ * This {@link Condition} can, of course, only be used with the write lock.
+ *
+ * <p>The read lock does not support a {@link Condition} and
+ * {@code readLock().newCondition()} throws
+ * {@code UnsupportedOperationException}.
+ *
+ * <li><b>Instrumentation</b>
+ * <p>This class supports methods to determine whether locks
+ * are held or contended. These methods are designed for monitoring
+ * system state, not for synchronization control.
+ * </ul>
+ *
+ * <p>Serialization of this class behaves in the same way as built-in
+ * locks: a deserialized lock is in the unlocked state, regardless of
+ * its state when serialized.
+ *
+ * <p><b>Sample usages</b>. Here is a code sketch showing how to exploit
+ * reentrancy to perform lock downgrading after updating a cache (exception
+ * handling is elided for simplicity):
+ * <pre>
+ * class CachedData {
+ * Object data;
+ * volatile boolean cacheValid;
+ * ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+ *
+ * void processCachedData() {
+ * rwl.readLock().lock();
+ * if (!cacheValid) {
+ * // Must release read lock before acquiring write lock
+ * rwl.readLock().unlock();
+ * rwl.writeLock().lock();
+ * // Recheck state because another thread might have acquired
+ * // write lock and changed state before we did.
+ * if (!cacheValid) {
+ * data = ...
+ * cacheValid = true;
+ * }
+ * // Downgrade by acquiring read lock before releasing write lock
+ * rwl.readLock().lock();
+ * rwl.writeLock().unlock(); // Unlock write, still hold read
+ * }
+ *
+ * use(data);
+ * rwl.readLock().unlock();
+ * }
+ * }
+ * </pre>
+ *
+ * ReentrantReadWriteLocks can be used to improve concurrency in some
+ * uses of some kinds of Collections. This is typically worthwhile
+ * only when the collections are expected to be large, accessed by
+ * more reader threads than writer threads, and entail operations with
+ * overhead that outweighs synchronization overhead. For example, here
+ * is a class using a TreeMap that is expected to be large and
+ * concurrently accessed.
+ *
+ * <pre>{@code
+ * class RWDictionary {
+ * private final Map<String, Data> m = new TreeMap<String, Data>();
+ * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+ * private final Lock r = rwl.readLock();
+ * private final Lock w = rwl.writeLock();
+ *
+ * public Data get(String key) {
+ * r.lock();
+ * try { return m.get(key); }
+ * finally { r.unlock(); }
+ * }
+ * public String[] allKeys() {
+ * r.lock();
+ * try { return m.keySet().toArray(); }
+ * finally { r.unlock(); }
+ * }
+ * public Data put(String key, Data value) {
+ * w.lock();
+ * try { return m.put(key, value); }
+ * finally { w.unlock(); }
+ * }
+ * public void clear() {
+ * w.lock();
+ * try { m.clear(); }
+ * finally { w.unlock(); }
+ * }
+ * }}</pre>
+ *
+ * <h3>Implementation Notes</h3>
+ *
+ * <p>This lock supports a maximum of 65535 recursive write locks
+ * and 65535 read locks. Attempts to exceed these limits result in
+ * {@link Error} throws from locking methods.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ *
+ */
+public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable {
+ private static final long serialVersionUID = -6992448646407690164L;
+ /** Inner class providing readlock */
+ private final ReentrantReadWriteLock.ReadLock readerLock;
+ /** Inner class providing writelock */
+ private final ReentrantReadWriteLock.WriteLock writerLock;
+ /** Performs all synchronization mechanics */
+ private final Sync sync;
+
+ /**
+ * Creates a new {@code ReentrantReadWriteLock} with
+ * default (nonfair) ordering properties.
+ */
+ public ReentrantReadWriteLock() {
+ this(false);
+ }
+
+ /**
+ * Creates a new {@code ReentrantReadWriteLock} with
+ * the given fairness policy.
+ *
+ * @param fair {@code true} if this lock should use a fair ordering policy
+ */
+ public ReentrantReadWriteLock(boolean fair) {
+ sync = (fair)? new FairSync() : new NonfairSync();
+ readerLock = new ReadLock(this);
+ writerLock = new WriteLock(this);
+ }
+
+ public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
+ public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }
+
+ /**
+ * Synchronization implementation for ReentrantReadWriteLock.
+ * Subclassed into fair and nonfair versions.
+ */
+ static abstract class Sync extends AbstractQueuedSynchronizer {
+ private static final long serialVersionUID = 6317671515068378041L;
+
+ /*
+ * Read vs write count extraction constants and functions.
+ * Lock state is logically divided into two shorts: The lower
+ * one representing the exclusive (writer) lock hold count,
+ * and the upper the shared (reader) hold count.
+ */
+
+ static final int SHARED_SHIFT = 16;
+ static final int SHARED_UNIT = (1 << SHARED_SHIFT);
+ static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;
+ static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
+
+ /** Returns the number of shared holds represented in count */
+ static int sharedCount(int c) { return c >>> SHARED_SHIFT; }
+ /** Returns the number of exclusive holds represented in count */
+ static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
+
+ /**
+ * A counter for per-thread read hold counts.
+ * Maintained as a ThreadLocal; cached in cachedHoldCounter
+ */
+ static final class HoldCounter {
+ int count;
+ // Use id, not reference, to avoid garbage retention
+ final long tid = Thread.currentThread().getId();
+ /** Decrement if positive; return previous value */
+ int tryDecrement() {
+ int c = count;
+ if (c > 0)
+ count = c - 1;
+ return c;
+ }
+ }
+
+ /**
+ * ThreadLocal subclass. Easiest to explicitly define for sake
+ * of deserialization mechanics.
+ */
+ static final class ThreadLocalHoldCounter
+ extends ThreadLocal<HoldCounter> {
+ public HoldCounter initialValue() {
+ return new HoldCounter();
+ }
+ }
+
+ /**
+ * The number of read locks held by current thread.
+ * Initialized only in constructor and readObject.
+ */
+ transient ThreadLocalHoldCounter readHolds;
+
+ /**
+ * The hold count of the last thread to successfully acquire
+ * readLock. This saves ThreadLocal lookup in the common case
+ * where the next thread to release is the last one to
+ * acquire. This is non-volatile since it is just used
+ * as a heuristic, and would be great for threads to cache.
+ */
+ transient HoldCounter cachedHoldCounter;
+
+ Sync() {
+ readHolds = new ThreadLocalHoldCounter();
+ setState(getState()); // ensures visibility of readHolds
+ }
+
+ /*
+ * Acquires and releases use the same code for fair and
+ * nonfair locks, but differ in whether/how they allow barging
+ * when queues are non-empty.
+ */
+
+ /**
+ * Return true if a reader thread that is otherwise
+ * eligible for lock should block because of policy
+ * for overtaking other waiting threads.
+ */
+ abstract boolean readerShouldBlock(Thread current);
+
+ /**
+ * Return true if a writer thread that is otherwise
+ * eligible for lock should block because of policy
+ * for overtaking other waiting threads.
+ */
+ abstract boolean writerShouldBlock(Thread current);
+
+ /*
+ * Note that tryRelease and tryAcquire can be called by
+ * Conditions. So it is possible that their arguments contain
+ * both read and write holds that are all released during a
+ * condition wait and re-established in tryAcquire.
+ */
+
+ protected final boolean tryRelease(int releases) {
+ int nextc = getState() - releases;
+ if (Thread.currentThread() != getExclusiveOwnerThread())
+ throw new IllegalMonitorStateException();
+ if (exclusiveCount(nextc) == 0) {
+ setExclusiveOwnerThread(null);
+ setState(nextc);
+ return true;
+ } else {
+ setState(nextc);
+ return false;
+ }
+ }
+
+ protected final boolean tryAcquire(int acquires) {
+ /*
+ * Walkthrough:
+ * 1. if read count nonzero or write count nonzero
+ * and owner is a different thread, fail.
+ * 2. If count would saturate, fail. (This can only
+ * happen if count is already nonzero.)
+ * 3. Otherwise, this thread is eligible for lock if
+ * it is either a reentrant acquire or
+ * queue policy allows it. If so, update state
+ * and set owner.
+ */
+ Thread current = Thread.currentThread();
+ int c = getState();
+ int w = exclusiveCount(c);
+ if (c != 0) {
+ // (Note: if c != 0 and w == 0 then shared count != 0)
+ if (w == 0 || current != getExclusiveOwnerThread())
+ return false;
+ if (w + exclusiveCount(acquires) > MAX_COUNT)
+ throw new Error("Maximum lock count exceeded");
+ }
+ if ((w == 0 && writerShouldBlock(current)) ||
+ !compareAndSetState(c, c + acquires))
+ return false;
+ setExclusiveOwnerThread(current);
+ return true;
+ }
+
+ protected final boolean tryReleaseShared(int unused) {
+ HoldCounter rh = cachedHoldCounter;
+ Thread current = Thread.currentThread();
+ if (rh == null || rh.tid != current.getId())
+ rh = readHolds.get();
+ if (rh.tryDecrement() <= 0)
+ throw new IllegalMonitorStateException();
+ for (;;) {
+ int c = getState();
+ int nextc = c - SHARED_UNIT;
+ if (compareAndSetState(c, nextc))
+ return nextc == 0;
+ }
+ }
+
+ protected final int tryAcquireShared(int unused) {
+ /*
+ * Walkthrough:
+ * 1. If write lock held by another thread, fail
+ * 2. If count saturated, throw error
+ * 3. Otherwise, this thread is eligible for
+ * lock wrt state, so ask if it should block
+ * because of queue policy. If not, try
+ * to grant by CASing state and updating count.
+ * Note that step does not check for reentrant
+ * acquires, which is postponed to full version
+ * to avoid having to check hold count in
+ * the more typical non-reentrant case.
+ * 4. If step 3 fails either because thread
+ * apparently not eligible or CAS fails,
+ * chain to version with full retry loop.
+ */
+ Thread current = Thread.currentThread();
+ int c = getState();
+ if (exclusiveCount(c) != 0 &&
+ getExclusiveOwnerThread() != current)
+ return -1;
+ if (sharedCount(c) == MAX_COUNT)
+ throw new Error("Maximum lock count exceeded");
+ if (!readerShouldBlock(current) &&
+ compareAndSetState(c, c + SHARED_UNIT)) {
+ HoldCounter rh = cachedHoldCounter;
+ if (rh == null || rh.tid != current.getId())
+ cachedHoldCounter = rh = readHolds.get();
+ rh.count++;
+ return 1;
+ }
+ return fullTryAcquireShared(current);
+ }
+
+ /**
+ * Full version of acquire for reads, that handles CAS misses
+ * and reentrant reads not dealt with in tryAcquireShared.
+ */
+ final int fullTryAcquireShared(Thread current) {
+ /*
+ * This code is in part redundant with that in
+ * tryAcquireShared but is simpler overall by not
+ * complicating tryAcquireShared with interactions between
+ * retries and lazily reading hold counts.
+ */
+ HoldCounter rh = cachedHoldCounter;
+ if (rh == null || rh.tid != current.getId())
+ rh = readHolds.get();
+ for (;;) {
+ int c = getState();
+ int w = exclusiveCount(c);
+ if ((w != 0 && getExclusiveOwnerThread() != current) ||
+ ((rh.count | w) == 0 && readerShouldBlock(current)))
+ return -1;
+ if (sharedCount(c) == MAX_COUNT)
+ throw new Error("Maximum lock count exceeded");
+ if (compareAndSetState(c, c + SHARED_UNIT)) {
+ cachedHoldCounter = rh; // cache for release
+ rh.count++;
+ return 1;
+ }
+ }
+ }
+
+ /**
+ * Performs tryLock for write, enabling barging in both modes.
+ * This is identical in effect to tryAcquire except for lack
+ * of calls to writerShouldBlock
+ */
+ final boolean tryWriteLock() {
+ Thread current = Thread.currentThread();
+ int c = getState();
+ if (c != 0) {
+ int w = exclusiveCount(c);
+ if (w == 0 ||current != getExclusiveOwnerThread())
+ return false;
+ if (w == MAX_COUNT)
+ throw new Error("Maximum lock count exceeded");
+ }
+ if (!compareAndSetState(c, c + 1))
+ return false;
+ setExclusiveOwnerThread(current);
+ return true;
+ }
+
+ /**
+ * Performs tryLock for read, enabling barging in both modes.
+ * This is identical in effect to tryAcquireShared except for
+ * lack of calls to readerShouldBlock
+ */
+ final boolean tryReadLock() {
+ Thread current = Thread.currentThread();
+ for (;;) {
+ int c = getState();
+ if (exclusiveCount(c) != 0 &&
+ getExclusiveOwnerThread() != current)
+ return false;
+ if (sharedCount(c) == MAX_COUNT)
+ throw new Error("Maximum lock count exceeded");
+ if (compareAndSetState(c, c + SHARED_UNIT)) {
+ HoldCounter rh = cachedHoldCounter;
+ if (rh == null || rh.tid != current.getId())
+ cachedHoldCounter = rh = readHolds.get();
+ rh.count++;
+ return true;
+ }
+ }
+ }
+
+ protected final boolean isHeldExclusively() {
+ // While we must in general read state before owner,
+ // we don't need to do so to check if current thread is owner
+ return getExclusiveOwnerThread() == Thread.currentThread();
+ }
+
+ // Methods relayed to outer class
+
+ final ConditionObject newCondition() {
+ return new ConditionObject();
+ }
+
+ final Thread getOwner() {
+ // Must read state before owner to ensure memory consistency
+ return ((exclusiveCount(getState()) == 0)?
+ null :
+ getExclusiveOwnerThread());
+ }
+
+ final int getReadLockCount() {
+ return sharedCount(getState());
+ }
+
+ final boolean isWriteLocked() {
+ return exclusiveCount(getState()) != 0;
+ }
+
+ final int getWriteHoldCount() {
+ return isHeldExclusively() ? exclusiveCount(getState()) : 0;
+ }
+
+ final int getReadHoldCount() {
+ return getReadLockCount() == 0? 0 : readHolds.get().count;
+ }
+
+ /**
+ * Reconstitute this lock instance from a stream
+ * @param s the stream
+ */
+ private void readObject(java.io.ObjectInputStream s)
+ throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ readHolds = new ThreadLocalHoldCounter();
+ setState(0); // reset to unlocked state
+ }
+
+ final int getCount() { return getState(); }
+ }
+
+ /**
+ * Nonfair version of Sync
+ */
+ final static class NonfairSync extends Sync {
+ private static final long serialVersionUID = -8159625535654395037L;
+ final boolean writerShouldBlock(Thread current) {
+ return false; // writers can always barge
+ }
+ final boolean readerShouldBlock(Thread current) {
+ /* As a heuristic to avoid indefinite writer starvation,
+ * block if the thread that momentarily appears to be head
+ * of queue, if one exists, is a waiting writer. This is
+ * only a probablistic effect since a new reader will not
+ * block if there is a waiting writer behind other enabled
+ * readers that have not yet drained from the queue.
+ */
+ return apparentlyFirstQueuedIsExclusive();
+ }
+ }
+
+ /**
+ * Fair version of Sync
+ */
+ final static class FairSync extends Sync {
+ private static final long serialVersionUID = -2274990926593161451L;
+ final boolean writerShouldBlock(Thread current) {
+ // only proceed if queue is empty or current thread at head
+ return !isFirst(current);
+ }
+ final boolean readerShouldBlock(Thread current) {
+ // only proceed if queue is empty or current thread at head
+ return !isFirst(current);
+ }
+ }
+
+ /**
+ * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
+ */
+ public static class ReadLock implements Lock, java.io.Serializable {
+ private static final long serialVersionUID = -5992448646407690164L;
+ private final Sync sync;
+
+ /**
+ * Constructor for use by subclasses
+ *
+ * @param lock the outer lock object
+ * @throws NullPointerException if the lock is null
+ */
+ protected ReadLock(ReentrantReadWriteLock lock) {
+ sync = lock.sync;
+ }
+
+ /**
+ * Acquires the read lock.
+ *
+ * <p>Acquires the read lock if the write lock is not held by
+ * another thread and returns immediately.
+ *
+ * <p>If the write lock is held by another thread then
+ * the current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until the read lock has been acquired.
+ */
+ public void lock() {
+ sync.acquireShared(1);
+ }
+
+ /**
+ * Acquires the read lock unless the current thread is
+ * {@linkplain Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the read lock if the write lock is not held
+ * by another thread and returns immediately.
+ *
+ * <p>If the write lock is held by another thread then the
+ * current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of two things happens:
+ *
+ * <ul>
+ *
+ * <li>The read lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread.
+ *
+ * </ul>
+ *
+ * <p>If the current thread:
+ *
+ * <ul>
+ *
+ * <li>has its interrupted status set on entry to this method; or
+ *
+ * <li>is {@linkplain Thread#interrupt interrupted} while
+ * acquiring the read lock,
+ *
+ * </ul>
+ *
+ * then {@link InterruptedException} is thrown and the current
+ * thread's interrupted status is cleared.
+ *
+ * <p>In this implementation, as this method is an explicit
+ * interruption point, preference is given to responding to
+ * the interrupt over normal or reentrant acquisition of the
+ * lock.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public void lockInterruptibly() throws InterruptedException {
+ sync.acquireSharedInterruptibly(1);
+ }
+
+ /**
+ * Acquires the read lock only if the write lock is not held by
+ * another thread at the time of invocation.
+ *
+ * <p>Acquires the read lock if the write lock is not held by
+ * another thread and returns immediately with the value
+ * {@code true}. Even when this lock has been set to use a
+ * fair ordering policy, a call to {@code tryLock()}
+ * <em>will</em> immediately acquire the read lock if it is
+ * available, whether or not other threads are currently
+ * waiting for the read lock. This &quot;barging&quot; behavior
+ * can be useful in certain circumstances, even though it
+ * breaks fairness. If you want to honor the fairness setting
+ * for this lock, then use {@link #tryLock(long, TimeUnit)
+ * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
+ * (it also detects interruption).
+ *
+ * <p>If the write lock is held by another thread then
+ * this method will return immediately with the value
+ * {@code false}.
+ *
+ * @return {@code true} if the read lock was acquired
+ */
+ public boolean tryLock() {
+ return sync.tryReadLock();
+ }
+
+ /**
+ * Acquires the read lock if the write lock is not held by
+ * another thread within the given waiting time and the
+ * current thread has not been {@linkplain Thread#interrupt
+ * interrupted}.
+ *
+ * <p>Acquires the read lock if the write lock is not held by
+ * another thread and returns immediately with the value
+ * {@code true}. If this lock has been set to use a fair
+ * ordering policy then an available lock <em>will not</em> be
+ * acquired if any other threads are waiting for the
+ * lock. This is in contrast to the {@link #tryLock()}
+ * method. If you want a timed {@code tryLock} that does
+ * permit barging on a fair lock then combine the timed and
+ * un-timed forms together:
+ *
+ * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
+ * </pre>
+ *
+ * <p>If the write lock is held by another thread then the
+ * current thread becomes disabled for thread scheduling
+ * purposes and lies dormant until one of three things happens:
+ *
+ * <ul>
+ *
+ * <li>The read lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread; or
+ *
+ * <li>The specified waiting time elapses.
+ *
+ * </ul>
+ *
+ * <p>If the read lock is acquired then the value {@code true} is
+ * returned.
+ *
+ * <p>If the current thread:
+ *
+ * <ul>
+ *
+ * <li>has its interrupted status set on entry to this method; or
+ *
+ * <li>is {@linkplain Thread#interrupt interrupted} while
+ * acquiring the read lock,
+ *
+ * </ul> then {@link InterruptedException} is thrown and the
+ * current thread's interrupted status is cleared.
+ *
+ * <p>If the specified waiting time elapses then the value
+ * {@code false} is returned. If the time is less than or
+ * equal to zero, the method will not wait at all.
+ *
+ * <p>In this implementation, as this method is an explicit
+ * interruption point, preference is given to responding to
+ * the interrupt over normal or reentrant acquisition of the
+ * lock, and over reporting the elapse of the waiting time.
+ *
+ * @param timeout the time to wait for the read lock
+ * @param unit the time unit of the timeout argument
+ * @return {@code true} if the read lock was acquired
+ * @throws InterruptedException if the current thread is interrupted
+ * @throws NullPointerException if the time unit is null
+ *
+ */
+ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
+ }
+
+ /**
+ * Attempts to release this lock.
+ *
+ * <p> If the number of readers is now zero then the lock
+ * is made available for write lock attempts.
+ */
+ public void unlock() {
+ sync.releaseShared(1);
+ }
+
+ /**
+ * Throws {@code UnsupportedOperationException} because
+ * {@code ReadLocks} do not support conditions.
+ *
+ * @throws UnsupportedOperationException always
+ */
+ public Condition newCondition() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns a string identifying this lock, as well as its lock state.
+ * The state, in brackets, includes the String {@code "Read locks ="}
+ * followed by the number of held read locks.
+ *
+ * @return a string identifying this lock, as well as its lock state
+ */
+ public String toString() {
+ int r = sync.getReadLockCount();
+ return super.toString() +
+ "[Read locks = " + r + "]";
+ }
+ }
+
+ /**
+ * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
+ */
+ public static class WriteLock implements Lock, java.io.Serializable {
+ private static final long serialVersionUID = -4992448646407690164L;
+ private final Sync sync;
+
+ /**
+ * Constructor for use by subclasses
+ *
+ * @param lock the outer lock object
+ * @throws NullPointerException if the lock is null
+ */
+ protected WriteLock(ReentrantReadWriteLock lock) {
+ sync = lock.sync;
+ }
+
+ /**
+ * Acquires the write lock.
+ *
+ * <p>Acquires the write lock if neither the read nor write lock
+ * are held by another thread
+ * and returns immediately, setting the write lock hold count to
+ * one.
+ *
+ * <p>If the current thread already holds the write lock then the
+ * hold count is incremented by one and the method returns
+ * immediately.
+ *
+ * <p>If the lock is held by another thread then the current
+ * thread becomes disabled for thread scheduling purposes and
+ * lies dormant until the write lock has been acquired, at which
+ * time the write lock hold count is set to one.
+ */
+ public void lock() {
+ sync.acquire(1);
+ }
+
+ /**
+ * Acquires the write lock unless the current thread is
+ * {@linkplain Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the write lock if neither the read nor write lock
+ * are held by another thread
+ * and returns immediately, setting the write lock hold count to
+ * one.
+ *
+ * <p>If the current thread already holds this lock then the
+ * hold count is incremented by one and the method returns
+ * immediately.
+ *
+ * <p>If the lock is held by another thread then the current
+ * thread becomes disabled for thread scheduling purposes and
+ * lies dormant until one of two things happens:
+ *
+ * <ul>
+ *
+ * <li>The write lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread.
+ *
+ * </ul>
+ *
+ * <p>If the write lock is acquired by the current thread then the
+ * lock hold count is set to one.
+ *
+ * <p>If the current thread:
+ *
+ * <ul>
+ *
+ * <li>has its interrupted status set on entry to this method;
+ * or
+ *
+ * <li>is {@linkplain Thread#interrupt interrupted} while
+ * acquiring the write lock,
+ *
+ * </ul>
+ *
+ * then {@link InterruptedException} is thrown and the current
+ * thread's interrupted status is cleared.
+ *
+ * <p>In this implementation, as this method is an explicit
+ * interruption point, preference is given to responding to
+ * the interrupt over normal or reentrant acquisition of the
+ * lock.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ */
+ public void lockInterruptibly() throws InterruptedException {
+ sync.acquireInterruptibly(1);
+ }
+
+ /**
+ * Acquires the write lock only if it is not held by another thread
+ * at the time of invocation.
+ *
+ * <p>Acquires the write lock if neither the read nor write lock
+ * are held by another thread
+ * and returns immediately with the value {@code true},
+ * setting the write lock hold count to one. Even when this lock has
+ * been set to use a fair ordering policy, a call to
+ * {@code tryLock()} <em>will</em> immediately acquire the
+ * lock if it is available, whether or not other threads are
+ * currently waiting for the write lock. This &quot;barging&quot;
+ * behavior can be useful in certain circumstances, even
+ * though it breaks fairness. If you want to honor the
+ * fairness setting for this lock, then use {@link
+ * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
+ * which is almost equivalent (it also detects interruption).
+ *
+ * <p> If the current thread already holds this lock then the
+ * hold count is incremented by one and the method returns
+ * {@code true}.
+ *
+ * <p>If the lock is held by another thread then this method
+ * will return immediately with the value {@code false}.
+ *
+ * @return {@code true} if the lock was free and was acquired
+ * by the current thread, or the write lock was already held
+ * by the current thread; and {@code false} otherwise.
+ */
+ public boolean tryLock( ) {
+ return sync.tryWriteLock();
+ }
+
+ /**
+ * Acquires the write lock if it is not held by another thread
+ * within the given waiting time and the current thread has
+ * not been {@linkplain Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the write lock if neither the read nor write lock
+ * are held by another thread
+ * and returns immediately with the value {@code true},
+ * setting the write lock hold count to one. If this lock has been
+ * set to use a fair ordering policy then an available lock
+ * <em>will not</em> be acquired if any other threads are
+ * waiting for the write lock. This is in contrast to the {@link
+ * #tryLock()} method. If you want a timed {@code tryLock}
+ * that does permit barging on a fair lock then combine the
+ * timed and un-timed forms together:
+ *
+ * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
+ * </pre>
+ *
+ * <p>If the current thread already holds this lock then the
+ * hold count is incremented by one and the method returns
+ * {@code true}.
+ *
+ * <p>If the lock is held by another thread then the current
+ * thread becomes disabled for thread scheduling purposes and
+ * lies dormant until one of three things happens:
+ *
+ * <ul>
+ *
+ * <li>The write lock is acquired by the current thread; or
+ *
+ * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+ * the current thread; or
+ *
+ * <li>The specified waiting time elapses
+ *
+ * </ul>
+ *
+ * <p>If the write lock is acquired then the value {@code true} is
+ * returned and the write lock hold count is set to one.
+ *
+ * <p>If the current thread:
+ *
+ * <ul>
+ *
+ * <li>has its interrupted status set on entry to this method;
+ * or
+ *
+ * <li>is {@linkplain Thread#interrupt interrupted} while
+ * acquiring the write lock,
+ *
+ * </ul>
+ *
+ * then {@link InterruptedException} is thrown and the current
+ * thread's interrupted status is cleared.
+ *
+ * <p>If the specified waiting time elapses then the value
+ * {@code false} is returned. If the time is less than or
+ * equal to zero, the method will not wait at all.
+ *
+ * <p>In this implementation, as this method is an explicit
+ * interruption point, preference is given to responding to
+ * the interrupt over normal or reentrant acquisition of the
+ * lock, and over reporting the elapse of the waiting time.
+ *
+ * @param timeout the time to wait for the write lock
+ * @param unit the time unit of the timeout argument
+ *
+ * @return {@code true} if the lock was free and was acquired
+ * by the current thread, or the write lock was already held by the
+ * current thread; and {@code false} if the waiting time
+ * elapsed before the lock could be acquired.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * @throws NullPointerException if the time unit is null
+ *
+ */
+ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
+ return sync.tryAcquireNanos(1, unit.toNanos(timeout));
+ }
+
+ /**
+ * Attempts to release this lock.
+ *
+ * <p>If the current thread is the holder of this lock then
+ * the hold count is decremented. If the hold count is now
+ * zero then the lock is released. If the current thread is
+ * not the holder of this lock then {@link
+ * IllegalMonitorStateException} is thrown.
+ *
+ * @throws IllegalMonitorStateException if the current thread does not
+ * hold this lock.
+ */
+ public void unlock() {
+ sync.release(1);
+ }
+
+ /**
+ * Returns a {@link Condition} instance for use with this
+ * {@link Lock} instance.
+ * <p>The returned {@link Condition} instance supports the same
+ * usages as do the {@link Object} monitor methods ({@link
+ * Object#wait() wait}, {@link Object#notify notify}, and {@link
+ * Object#notifyAll notifyAll}) when used with the built-in
+ * monitor lock.
+ *
+ * <ul>
+ *
+ * <li>If this write lock is not held when any {@link
+ * Condition} method is called then an {@link
+ * IllegalMonitorStateException} is thrown. (Read locks are
+ * held independently of write locks, so are not checked or
+ * affected. However it is essentially always an error to
+ * invoke a condition waiting method when the current thread
+ * has also acquired read locks, since other threads that
+ * could unblock it will not be able to acquire the write
+ * lock.)
+ *
+ * <li>When the condition {@linkplain Condition#await() waiting}
+ * methods are called the write lock is released and, before
+ * they return, the write lock is reacquired and the lock hold
+ * count restored to what it was when the method was called.
+ *
+ * <li>If a thread is {@linkplain Thread#interrupt interrupted} while
+ * waiting then the wait will terminate, an {@link
+ * InterruptedException} will be thrown, and the thread's
+ * interrupted status will be cleared.
+ *
+ * <li> Waiting threads are signalled in FIFO order.
+ *
+ * <li>The ordering of lock reacquisition for threads returning
+ * from waiting methods is the same as for threads initially
+ * acquiring the lock, which is in the default case not specified,
+ * but for <em>fair</em> locks favors those threads that have been
+ * waiting the longest.
+ *
+ * </ul>
+ *
+ * @return the Condition object
+ */
+ public Condition newCondition() {
+ return sync.newCondition();
+ }
+
+ /**
+ * Returns a string identifying this lock, as well as its lock
+ * state. The state, in brackets includes either the String
+ * {@code "Unlocked"} or the String {@code "Locked by"}
+ * followed by the {@linkplain Thread#getName name} of the owning thread.
+ *
+ * @return a string identifying this lock, as well as its lock state
+ */
+ public String toString() {
+ Thread o = sync.getOwner();
+ return super.toString() + ((o == null) ?
+ "[Unlocked]" :
+ "[Locked by thread " + o.getName() + "]");
+ }
+
+ /**
+ * Queries if this write lock is held by the current thread.
+ * Identical in effect to {@link
+ * ReentrantReadWriteLock#isWriteLockedByCurrentThread}.
+ *
+ * @return {@code true} if the current thread holds this lock and
+ * {@code false} otherwise
+ * @since 1.6
+ */
+ public boolean isHeldByCurrentThread() {
+ return sync.isHeldExclusively();
+ }
+
+ /**
+ * Queries the number of holds on this write lock by the current
+ * thread. A thread has a hold on a lock for each lock action
+ * that is not matched by an unlock action. Identical in effect
+ * to {@link ReentrantReadWriteLock#getWriteHoldCount}.
+ *
+ * @return the number of holds on this lock by the current thread,
+ * or zero if this lock is not held by the current thread
+ * @since 1.6
+ */
+ public int getHoldCount() {
+ return sync.getWriteHoldCount();
+ }
+ }
+
+ // Instrumentation and status
+
+ /**
+ * Returns {@code true} if this lock has fairness set true.
+ *
+ * @return {@code true} if this lock has fairness set true
+ */
+ public final boolean isFair() {
+ return sync instanceof FairSync;
+ }
+
+ /**
+ * Returns the thread that currently owns the write lock, or
+ * {@code null} if not owned. When this method is called by a
+ * thread that is not the owner, the return value reflects a
+ * best-effort approximation of current lock status. For example,
+ * the owner may be momentarily {@code null} even if there are
+ * threads trying to acquire the lock but have not yet done so.
+ * This method is designed to facilitate construction of
+ * subclasses that provide more extensive lock monitoring
+ * facilities.
+ *
+ * @return the owner, or {@code null} if not owned
+ */
+ protected Thread getOwner() {
+ return sync.getOwner();
+ }
+
+ /**
+ * Queries the number of read locks held for this lock. This
+ * method is designed for use in monitoring system state, not for
+ * synchronization control.
+ * @return the number of read locks held.
+ */
+ public int getReadLockCount() {
+ return sync.getReadLockCount();
+ }
+
+ /**
+ * Queries if the write lock is held by any thread. This method is
+ * designed for use in monitoring system state, not for
+ * synchronization control.
+ *
+ * @return {@code true} if any thread holds the write lock and
+ * {@code false} otherwise
+ */
+ public boolean isWriteLocked() {
+ return sync.isWriteLocked();
+ }
+
+ /**
+ * Queries if the write lock is held by the current thread.
+ *
+ * @return {@code true} if the current thread holds the write lock and
+ * {@code false} otherwise
+ */
+ public boolean isWriteLockedByCurrentThread() {
+ return sync.isHeldExclusively();
+ }
+
+ /**
+ * Queries the number of reentrant write holds on this lock by the
+ * current thread. A writer thread has a hold on a lock for
+ * each lock action that is not matched by an unlock action.
+ *
+ * @return the number of holds on the write lock by the current thread,
+ * or zero if the write lock is not held by the current thread
+ */
+ public int getWriteHoldCount() {
+ return sync.getWriteHoldCount();
+ }
+
+ /**
+ * Queries the number of reentrant read holds on this lock by the
+ * current thread. A reader thread has a hold on a lock for
+ * each lock action that is not matched by an unlock action.
+ *
+ * @return the number of holds on the read lock by the current thread,
+ * or zero if the read lock is not held by the current thread
+ * @since 1.6
+ */
+ public int getReadHoldCount() {
+ return sync.getReadHoldCount();
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire the write lock. Because the actual set of threads may
+ * change dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive lock monitoring facilities.
+ *
+ * @return the collection of threads
+ */
+ protected Collection<Thread> getQueuedWriterThreads() {
+ return sync.getExclusiveQueuedThreads();
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire the read lock. Because the actual set of threads may
+ * change dynamically while constructing this result, the returned
+ * collection is only a best-effort estimate. The elements of the
+ * returned collection are in no particular order. This method is
+ * designed to facilitate construction of subclasses that provide
+ * more extensive lock monitoring facilities.
+ *
+ * @return the collection of threads
+ */
+ protected Collection<Thread> getQueuedReaderThreads() {
+ return sync.getSharedQueuedThreads();
+ }
+
+ /**
+ * Queries whether any threads are waiting to acquire the read or
+ * write lock. Note that because cancellations may occur at any
+ * time, a {@code true} return does not guarantee that any other
+ * thread will ever acquire a lock. This method is designed
+ * primarily for use in monitoring of the system state.
+ *
+ * @return {@code true} if there may be other threads waiting to
+ * acquire the lock
+ */
+ public final boolean hasQueuedThreads() {
+ return sync.hasQueuedThreads();
+ }
+
+ /**
+ * Queries whether the given thread is waiting to acquire either
+ * the read or write lock. Note that because cancellations may
+ * occur at any time, a {@code true} return does not guarantee
+ * that this thread will ever acquire a lock. This method is
+ * designed primarily for use in monitoring of the system state.
+ *
+ * @param thread the thread
+ * @return {@code true} if the given thread is queued waiting for this lock
+ * @throws NullPointerException if the thread is null
+ */
+ public final boolean hasQueuedThread(Thread thread) {
+ return sync.isQueued(thread);
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting to acquire
+ * either the read or write lock. The value is only an estimate
+ * because the number of threads may change dynamically while this
+ * method traverses internal data structures. This method is
+ * designed for use in monitoring of the system state, not for
+ * synchronization control.
+ *
+ * @return the estimated number of threads waiting for this lock
+ */
+ public final int getQueueLength() {
+ return sync.getQueueLength();
+ }
+
+ /**
+ * Returns a collection containing threads that may be waiting to
+ * acquire either the read or write lock. Because the actual set
+ * of threads may change dynamically while constructing this
+ * result, the returned collection is only a best-effort estimate.
+ * The elements of the returned collection are in no particular
+ * order. This method is designed to facilitate construction of
+ * subclasses that provide more extensive monitoring facilities.
+ *
+ * @return the collection of threads
+ */
+ protected Collection<Thread> getQueuedThreads() {
+ return sync.getQueuedThreads();
+ }
+
+ /**
+ * Queries whether any threads are waiting on the given condition
+ * associated with the write lock. Note that because timeouts and
+ * interrupts may occur at any time, a {@code true} return does
+ * not guarantee that a future {@code signal} will awaken any
+ * threads. This method is designed primarily for use in
+ * monitoring of the system state.
+ *
+ * @param condition the condition
+ * @return {@code true} if there are any waiting threads
+ * @throws IllegalMonitorStateException if this lock is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if the condition is null
+ */
+ public boolean hasWaiters(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns an estimate of the number of threads waiting on the
+ * given condition associated with the write lock. Note that because
+ * timeouts and interrupts may occur at any time, the estimate
+ * serves only as an upper bound on the actual number of waiters.
+ * This method is designed for use in monitoring of the system
+ * state, not for synchronization control.
+ *
+ * @param condition the condition
+ * @return the estimated number of waiting threads
+ * @throws IllegalMonitorStateException if this lock is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if the condition is null
+ */
+ public int getWaitQueueLength(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns a collection containing those threads that may be
+ * waiting on the given condition associated with the write lock.
+ * Because the actual set of threads may change dynamically while
+ * constructing this result, the returned collection is only a
+ * best-effort estimate. The elements of the returned collection
+ * are in no particular order. This method is designed to
+ * facilitate construction of subclasses that provide more
+ * extensive condition monitoring facilities.
+ *
+ * @param condition the condition
+ * @return the collection of threads
+ * @throws IllegalMonitorStateException if this lock is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if the condition is null
+ */
+ protected Collection<Thread> getWaitingThreads(Condition condition) {
+ if (condition == null)
+ throw new NullPointerException();
+ if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
+ throw new IllegalArgumentException("not owner");
+ return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
+ }
+
+ /**
+ * Returns a string identifying this lock, as well as its lock state.
+ * The state, in brackets, includes the String {@code "Write locks ="}
+ * followed by the number of reentrantly held write locks, and the
+ * String {@code "Read locks ="} followed by the number of held
+ * read locks.
+ *
+ * @return a string identifying this lock, as well as its lock state
+ */
+ public String toString() {
+ int c = sync.getCount();
+ int w = Sync.exclusiveCount(c);
+ int r = Sync.sharedCount(c);
+
+ return super.toString() +
+ "[Write locks = " + w + ", Read locks = " + r + "]";
+ }
+
+}