You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by nd...@apache.org on 2006/09/11 01:59:35 UTC
svn commit: r442038 [9/19] - in
/incubator/harmony/standard/classlib/trunk/modules/concurrent: ./ src/
src/main/ src/main/java/ src/main/java/java/ src/main/java/java/util/
src/main/java/java/util/concurrent/
src/main/java/java/util/concurrent/atomic/ ...
Added: incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/Condition.java
URL: http://svn.apache.org/viewvc/incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/Condition.java?view=auto&rev=442038
==============================================================================
--- incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/Condition.java (added)
+++ incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/Condition.java Sun Sep 10 16:59:30 2006
@@ -0,0 +1,439 @@
+/*
+ * 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;
+
+/**
+ * <tt>Condition</tt> factors out the <tt>Object</tt> 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 <tt>Lock</tt> replaces the use of <tt>synchronized</tt> methods
+ * and statements, a <tt>Condition</tt> 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 "wait") 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 <tt>Object.wait</tt>.
+ *
+ * <p>A <tt>Condition</tt> instance is intrinsically bound to a lock.
+ * To obtain a <tt>Condition</tt> 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
+ * <tt>put</tt> and <tt>take</tt> methods. If a
+ * <tt>take</tt> is attempted on an empty buffer, then the thread will block
+ * until an item becomes available; if a <tt>put</tt> is attempted on a
+ * full buffer, then the thread will block until a space becomes available.
+ * We would like to keep waiting <tt>put</tt> threads and <tt>take</tt>
+ * 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>Lock lock = new ReentrantLock();</b>
+ * final Condition notFull = <b>lock.newCondition(); </b>
+ * final Condition notEmpty = <b>lock.newCondition(); </b>
+ *
+ * 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 <tt>Condition</tt> implementation can provide behavior and semantics
+ * that is
+ * different from that of the <tt>Object</tt> 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 <tt>Condition</tt> instances are just normal objects and can
+ * themselves be used as the target in a <tt>synchronized</tt> statement,
+ * and can have their own monitor {@link Object#wait wait} and
+ * {@link Object#notify notification} methods invoked.
+ * Acquiring the monitor lock of a <tt>Condition</tt> instance, or using its
+ * monitor methods, has no specified relationship with acquiring the
+ * {@link Lock} associated with that <tt>Condition</tt> or the use of its
+ * {@link #await waiting} and {@link #signal signalling} methods.
+ * It is recommended that to avoid confusion you never use <tt>Condition</tt>
+ * instances in this way, except perhaps within their own implementation.
+ *
+ * <p>Except where noted, passing a <tt>null</tt> value for any parameter
+ * will result in a {@link NullPointerException} being thrown.
+ *
+ * <h3>Implementation Considerations</h3>
+ *
+ * <p>When waiting upon a <tt>Condition</tt>, a "<em>spurious
+ * wakeup</em>" 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
+ * <tt>Condition</tt> 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
+ * {@link Thread#interrupt interrupted}.
+ *
+ * <p>The lock associated with this <tt>Condition</tt> 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
+ * <tt>Condition</tt> 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
+ * <tt>Condition</tt>; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread, and interruption of thread suspension is supported; or
+ * <li>A "<em>spurious wakeup</em>" 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 {@link 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
+ * <tt>Condition</tt> 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
+ * <tt>Condition</tt> 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
+ * <tt>Condition</tt>; or
+ * <li>A "<em>spurious wakeup</em>" 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 interrupt status is set when it enters
+ * this method, or it is {@link Thread#interrupt interrupted}
+ * while waiting, it will continue to wait until signalled. When it finally
+ * returns from this method its <em>interrupted status</em> will still
+ * be set.
+ *
+ * <p><b>Implementation Considerations</b>
+ * <p>The current thread is assumed to hold the lock associated with this
+ * <tt>Condition</tt> 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
+ * <tt>Condition</tt> 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
+ * <tt>Condition</tt>; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread, and interruption of thread suspension is supported; or
+ * <li>The specified waiting time elapses; or
+ * <li>A "<em>spurious wakeup</em>" 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 {@link 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 <tt>nanosTimeout</tt>
+ * 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 > 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
+ * <tt>Condition</tt> 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 A value less than or equal to zero if the wait has
+ * timed out; otherwise an estimate, that
+ * is strictly less than the <tt>nanosTimeout</tt> argument,
+ * of the time still remaining when this method returned.
+ *
+ * @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)) > 0
+ * </pre>
+ * @param time the maximum time to wait
+ * @param unit the time unit of the <tt>time</tt> argument.
+ * @return <tt>false</tt> if the waiting time detectably elapsed
+ * before return from the method, else <tt>true</tt>.
+ * @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
+ * <tt>Condition</tt> 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
+ * <tt>Condition</tt>; or
+ * <li>Some other thread {@link Thread#interrupt interrupts} the current
+ * thread, and interruption of thread suspension is supported; or
+ * <li>The specified deadline elapses; or
+ * <li>A "<em>spurious wakeup</em>" 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 {@link 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
+ * <tt>Condition</tt> 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 <tt>false</tt> if the deadline has
+ * elapsed upon return, else <tt>true</tt>.
+ *
+ * @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 <tt>await</tt>.
+ **/
+ void signal();
+
+ /**
+ * Wake 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 <tt>await</tt>.
+ **/
+ void signalAll();
+
+}
+
+
+
+
+
+
+
Propchange: incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/Condition.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/Lock.java
URL: http://svn.apache.org/viewvc/incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/Lock.java?view=auto&rev=442038
==============================================================================
--- incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/Lock.java (added)
+++ incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/Lock.java Sun Sep 10 16:59:30 2006
@@ -0,0 +1,329 @@
+/*
+ * 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;
+
+/**
+ * <tt>Lock</tt> implementations provide more extensive locking
+ * operations than can be obtained using <tt>synchronized</tt> 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 <tt>synchronized</tt> 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 <tt>synchronized</tt> 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
+ * "hand-over-hand" or "chain locking": 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
+ * <tt>Lock</tt> 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 <tt>synchronized</tt>
+ * 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><tt>Lock</tt> implementations provide additional functionality
+ * over the use of <tt>synchronized</tt> 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 <tt>Lock</tt> 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 <tt>Lock</tt> instances are just normal objects and can
+ * themselves be used as the target in a <tt>synchronized</tt> statement.
+ * Acquiring the
+ * monitor lock of a <tt>Lock</tt> 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 <tt>Lock</tt>
+ * instances in this way, except within their own implementation.
+ *
+ * <p>Except where noted, passing a <tt>null</tt> value for any
+ * parameter will result in a {@link NullPointerException} being
+ * thrown.
+ *
+ * <h3>Memory Synchronization</h3>
+ * <p>All <tt>Lock</tt> implementations <em>must</em> enforce the same
+ * memory synchronization semantics as provided by the built-in monitor lock:
+ * <ul>
+ * <li>A successful lock operation acts like a successful
+ * <tt>monitorEnter</tt> action
+ * <li>A successful <tt>unlock</tt> operation acts like a successful
+ * <tt>monitorExit</tt> 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 <tt>Lock</tt>
+ * 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 <tt>Lock</tt> 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
+ * <tt>Lock</tt> implementation.
+ *
+ **/
+ void lock();
+
+ /**
+ * Acquires the lock unless the current thread is
+ * {@link 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 {@link 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 {@link 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 <tt>Lock</tt> 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 <tt>Lock</tt> implementation.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * while acquiring the lock (and interruption of lock acquisition is
+ * supported).
+ *
+ * @see Thread#interrupt
+ *
+ **/
+ 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 <tt>true</tt>.
+ * If the lock is not available then this method will return
+ * immediately with the value <tt>false</tt>.
+ * <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 <tt>true</tt> if the lock was acquired and <tt>false</tt>
+ * otherwise.
+ **/
+ boolean tryLock();
+
+ /**
+ * Acquires the lock if it is free within the given waiting time and the
+ * current thread has not been {@link Thread#interrupt interrupted}.
+ *
+ * <p>If the lock is available this method returns immediately
+ * with the value <tt>true</tt>.
+ * 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 {@link 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 <tt>true</tt> is returned.
+ * <p>If the current thread:
+ * <ul>
+ * <li>has its interrupted status set on entry to this method; or
+ * <li>is {@link 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 <tt>false</tt>
+ * 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 <tt>Lock</tt> 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
+ * <tt>Lock</tt> implementation.
+ *
+ * @param time the maximum time to wait for the lock
+ * @param unit the time unit of the <tt>time</tt> argument.
+ * @return <tt>true</tt> if the lock was acquired and <tt>false</tt>
+ * 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).
+ *
+ * @see Thread#interrupt
+ *
+ **/
+ boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
+
+ /**
+ * Releases the lock.
+ * <p><b>Implementation Considerations</b>
+ * <p>A <tt>Lock</tt> 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 <tt>Lock</tt> implementation.
+ **/
+ void unlock();
+
+ /**
+ * Returns a new {@link Condition} instance that is bound to this
+ * <tt>Lock</tt> 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
+ * <tt>Lock</tt> implementation and must be documented by that
+ * implementation.
+ *
+ * @return A new {@link Condition} instance for this <tt>Lock</tt>
+ * instance.
+ * @throws UnsupportedOperationException if this <tt>Lock</tt>
+ * implementation does not support conditions.
+ **/
+ Condition newCondition();
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
Propchange: incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/Lock.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
URL: http://svn.apache.org/viewvc/incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java?view=auto&rev=442038
==============================================================================
--- incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java (added)
+++ incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java Sun Sep 10 16:59:30 2006
@@ -0,0 +1,178 @@
+/*
+ * 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 <tt>park</tt> will return immediately
+ * if the permit is available, consuming it in the process; otherwise
+ * it <em>may</em> block. A call to <tt>unpark</tt> 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 <tt>park</tt> and <tt>unpark</tt> provide efficient
+ * means of blocking and unblocking threads that do not encounter the
+ * problems that cause the deprecated methods <tt>Thread.suspend</tt>
+ * and <tt>Thread.resume</tt> to be unusable for such purposes: Races
+ * between one thread invoking <tt>park</tt> and another thread trying
+ * to <tt>unpark</tt> it will preserve liveness, due to the
+ * permit. Additionally, <tt>park</tt> will return if the caller's
+ * thread was interrupted, and timeout versions are supported. The
+ * <tt>park</tt> 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 <tt>park</tt> serves as an
+ * optimization of a "busy wait" that does not waste as much time
+ * spinning, but must be paired with an <tt>unpark</tt> to be
+ * effective.
+ *
+ * <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.
+ *
+ * <p><b>Sample Usage.</b> Here is a sketch of a First-in-first-out
+ * non-reentrant lock class.
+ * <pre>
+ * class FIFOMutex {
+ * private AtomicBoolean locked = new AtomicBoolean(false);
+ * private 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();
+ * 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();
+
+ /**
+ * Make available the permit for the given thread, if it
+ * was not already available. If the thread was blocked on
+ * <tt>park</tt> then it will unblock. Otherwise, its next call
+ * to <tt>park</tt> 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 <tt>null</tt>, 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 <tt>unpark</tt> with the current thread
+ * as the target; or
+ * <li>Some other thread {@link 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 <tt>unpark</tt> with the current thread
+ * as the target; or
+ * <li>Some other thread {@link 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 <tt>unpark</tt> with the current thread
+ * as the target; or
+ * <li>Some other thread {@link 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);
+ }
+
+}
+
+
Propchange: incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/LockSupport.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java
URL: http://svn.apache.org/viewvc/incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java?view=auto&rev=442038
==============================================================================
--- incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java (added)
+++ incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java Sun Sep 10 16:59:30 2006
@@ -0,0 +1,97 @@
+/*
+ * 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>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 "in-order" 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 write 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();
+}
Propchange: incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/ReadWriteLock.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java
URL: http://svn.apache.org/viewvc/incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java?view=auto&rev=442038
==============================================================================
--- incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java (added)
+++ incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java Sun Sep 10 16:59:30 2006
@@ -0,0 +1,727 @@
+/*
+ * 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
+ * <tt>synchronized</tt> methods and statements, but with extended
+ * capabilities.
+ *
+ * <p> A <tt>ReentrantLock</tt> is <em>owned</em> by the thread last
+ * successfully locking, but not yet unlocking it. A thread invoking
+ * <tt>lock</tt> 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 <tt>true</tt>, 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.
+ *
+ * <p> It is recommended practice to <em>always</em> immediately
+ * follow a call to <tt>lock</tt> with a <tt>try</tt> 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 <tt>isLocked</tt> and
+ * <tt>getLockQueueLength</tt>, as well as some associated
+ * <tt>protected</tt> 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 2147483648 recursive locks by
+ * the same thread.
+ *
+ * @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 {
+ /** Current owner thread */
+ transient Thread owner;
+
+ /**
+ * Perform {@link Lock#lock}. The main reason for subclassing
+ * is to allow fast path for nonfair version.
+ */
+ abstract void lock();
+
+ /**
+ * Perform 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)) {
+ owner = current;
+ return true;
+ }
+ }
+ else if (current == owner) {
+ setState(c+acquires);
+ return true;
+ }
+ return false;
+ }
+
+ protected final boolean tryRelease(int releases) {
+ int c = getState() - releases;
+ if (Thread.currentThread() != owner)
+ throw new IllegalMonitorStateException();
+ boolean free = false;
+ if (c == 0) {
+ free = true;
+ owner = null;
+ }
+ setState(c);
+ return free;
+ }
+
+ protected final boolean isHeldExclusively() {
+ return getState() != 0 && owner == Thread.currentThread();
+ }
+
+ final ConditionObject newCondition() {
+ return new ConditionObject();
+ }
+
+ // Methods relayed from outer class
+
+ final Thread getOwner() {
+ int c = getState();
+ Thread o = owner;
+ return (c == 0)? null : o;
+ }
+
+ final int getHoldCount() {
+ int c = getState();
+ Thread o = owner;
+ return (o == Thread.currentThread())? c : 0;
+ }
+
+ final boolean isLocked() {
+ return getState() != 0;
+ }
+
+ /**
+ * 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();
+ setState(0); // reset to unlocked state
+ }
+ }
+
+ /**
+ * Sync object for non-fair locks
+ */
+ final static class NonfairSync extends Sync {
+ /**
+ * Perform lock. Try immediate barge, backing up to normal
+ * acquire on failure.
+ */
+ final void lock() {
+ if (compareAndSetState(0, 1))
+ owner = 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 {
+ 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) {
+ Thread first = getFirstQueuedThread();
+ if ((first == null || first == current) &&
+ compareAndSetState(0, acquires)) {
+ owner = current;
+ return true;
+ }
+ }
+ else if (current == owner) {
+ setState(c+acquires);
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Creates an instance of <tt>ReentrantLock</tt>.
+ * This is equivalent to using <tt>ReentrantLock(false)</tt>.
+ */
+ public ReentrantLock() {
+ sync = new NonfairSync();
+ }
+
+ /**
+ * Creates an instance of <tt>ReentrantLock</tt> with the
+ * given fairness policy.
+ * @param fair true if this lock will be fair; else false
+ */
+ 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
+ * {@link 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 {@link 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 {@link 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 <tt>true</tt>, setting the
+ * lock hold count to one. Even when this lock has been set to use a
+ * fair ordering policy, a call to <tt>tryLock()</tt> <em>will</em>
+ * immediately acquire the lock if it is available, whether or not
+ * other threads are currently waiting for the lock.
+ * This "barging" 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 <tt>true</tt>.
+ *
+ * <p>If the lock is held by another thread then this method will return
+ * immediately with the value <tt>false</tt>.
+ *
+ * @return <tt>true</tt> if the lock was free and was acquired by the
+ * current thread, or the lock was already held by the current thread; and
+ * <tt>false</tt> 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
+ * {@link Thread#interrupt interrupted}.
+ *
+ * <p>Acquires the lock if it is not held by another thread and returns
+ * immediately with the value <tt>true</tt>, 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 <tt>tryLock</tt> 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 <tt>true</tt>.
+ *
+ * <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 {@link Thread#interrupt interrupts} the current
+ * thread; or
+ *
+ * <li>The specified waiting time elapses
+ *
+ * </ul>
+ *
+ * <p>If the lock is acquired then the value <tt>true</tt> 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 {@link 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 <tt>false</tt>
+ * 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 <tt>true</tt> if the lock was free and was acquired by the
+ * current thread, or the lock was already held by the current thread; and
+ * <tt>false</tt> if the waiting time elapsed before the lock could be
+ * acquired.
+ *
+ * @throws InterruptedException if the current thread is interrupted
+ * @throws NullPointerException if 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}
+ * {@link Condition#await() waiting} or {@link Condition#signal
+ * signalling} methods are called, then an {@link
+ * IllegalMonitorStateException} is thrown.
+ *
+ * <li>When the condition {@link 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 {@link 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 <tt>true</tt> if current thread holds this lock and
+ * <tt>false</tt> 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 <tt>true</tt> if any thread holds this lock and
+ * <tt>false</tt> otherwise.
+ */
+ public boolean isLocked() {
+ return sync.isLocked();
+ }
+
+ /**
+ * Returns true if this lock has fairness set true.
+ * @return true if this lock has fairness set true.
+ */
+ public final boolean isFair() {
+ return sync instanceof FairSync;
+ }
+
+ /**
+ * Returns the thread that currently owns the exclusive lock, or
+ * <tt>null</tt> if not owned. Note that the owner may be
+ * momentarily <tt>null</tt> 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 <tt>null</tt> if not owned.
+ */
+ protected Thread getOwner() {
+ return sync.getOwner();
+ }
+
+ /**
+ * Queries whether any threads are waiting to acquire. Note that
+ * because cancellations may occur at any time, a <tt>true</tt>
+ * return does not guarantee that any other thread will ever
+ * acquire. This method is designed primarily for use in
+ * monitoring of the system state.
+ *
+ * @return 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
+ * <tt>true</tt> return does not guarantee that this thread
+ * will ever acquire. This method is designed primarily for use
+ * in monitoring of the system state.
+ *
+ * @param thread the thread
+ * @return true if the given thread is queued waiting for this lock.
+ * @throws NullPointerException if thread is null
+ */
+ public final boolean hasQueuedThread(Thread thread) {
+ return sync.isQueued(thread);
+ }
+
+
+ /**
+ * 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 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. 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 <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 this lock
+ * is not held
+ * @throws IllegalArgumentException if the given condition is
+ * not associated with this lock
+ * @throws NullPointerException if condition 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 condition 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 condition 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
+ * "Unlocked" or the String "Locked by"
+ * followed by the {@link Thread#getName} of the owning thread.
+ * @return a string identifying this lock, as well as its lock state.
+ */
+ public String toString() {
+ Thread owner = sync.getOwner();
+ return super.toString() + ((owner == null) ?
+ "[Unlocked]" :
+ "[Locked by thread " + owner.getName() + "]");
+ }
+}
Propchange: incubator/harmony/standard/classlib/trunk/modules/concurrent/src/main/java/java/util/concurrent/locks/ReentrantLock.java
------------------------------------------------------------------------------
svn:eol-style = native