You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2006/07/01 00:37:29 UTC

svn commit: r418401 [17/32] - in /incubator/openjpa/trunk: openjpa-lib/ openjpa-lib/src/main/java/org/apache/openjpa/lib/ant/ openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/ openjpa-lib/src/...

Modified: incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/ReentrantLock.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/ReentrantLock.java?rev=418401&r1=418400&r2=418401&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/ReentrantLock.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/ReentrantLock.java Fri Jun 30 15:37:18 2006
@@ -1,19 +1,15 @@
 /*
  * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
+ *  Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *  Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 /*
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
@@ -23,72 +19,53 @@
 
 import java.util.*;
 
-
 /**
  * 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
+ * <tt>synchronized</tt> methods and statements, but with extended capabilities.
+ *   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
+ *   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
+ * 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.
+ * 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
+ *   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> 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
+ *  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
+ *   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
+ *   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
  * @author Dawid Kurzyniec
@@ -96,584 +73,60 @@
 public class ReentrantLock implements Lock, java.io.Serializable,
     CondVar.ExclusiveLock {
     private static final long serialVersionUID = 7373984872572414699L;
+
     private final Sync sync;
 
-    /**
-     * Creates an instance of <tt>ReentrantLock</tt>.
-     * This is equivalent to using <tt>ReentrantLock(false)</tt>.
-     */
-    public ReentrantLock() {
-        sync = new NonfairSync();
-    }
+    static abstract class Sync implements java.io.Serializable {
+        private static final long serialVersionUID = -5179523762034025860L;
 
-    /**
-     * 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) ? (Sync) new FairSync() : new NonfairSync();
-    }
+        protected transient Thread owner_ = null;
+        protected transient int holds_ = 0;
 
-    /**
-     * 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();
-    }
+        protected Sync() {}
 
-    /**
-     * 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.lockInterruptibly();
-    }
+        public abstract void lock();
 
-    /**
-     * 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 &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 <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.tryLock();
-    }
+        public abstract void lockInterruptibly() throws InterruptedException;
 
-    /**
-     * 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.tryLock(unit.toNanos(timeout));
-    }
+        final void incHolds() {
+            int nextHolds = ++holds_;
+            if (nextHolds < 0)
+                throw new Error("Maximum lock count exceeded");
+            holds_ = nextHolds;
+        }
 
-    /**
-     * 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.unlock();
-    }
+        public boolean tryLock() {
+            Thread caller = Thread.currentThread();
+            synchronized (this) {
+                if (owner_ == null) {
+                    owner_ = caller;
+                    holds_ = 1;
+                    return true;
+                } else if (caller == owner_) {
+                    incHolds();
+                    return true;
+                }
+            }
+            return false;
+        }
 
-    /**
-     * 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 isFair() ? new FIFOCondVar(this) : new CondVar(this);
-    }
+        public abstract boolean tryLock(long nanos) throws InterruptedException;
 
-    /**
-     * 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();
-    }
+        public abstract void unlock();
 
-    /**
-     * 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.isHeldByCurrentThread();
-    }
+        public synchronized int getHoldCount() {
+            return isHeldByCurrentThread() ? holds_ : 0;
+        }
 
-    /**
-     * 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();
-    }
+        public synchronized boolean isHeldByCurrentThread() {
+            return holds_ > 0 && Thread.currentThread() == owner_;
+        }
 
-    /**
-     * Returns true if this lock has fairness set true.
-     * @return true if this lock has fairness set true.
-     */
-    public final boolean isFair() {
-        return sync.isFair();
-    }
+        public synchronized boolean isLocked() {
+            return owner_ != null;
+        }
 
-    /**
-     * <tt>null</tt> 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 <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 this lock. 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 lock.  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 lock.  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 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 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) {
-        return asCondVar(condition).hasWaiters();
-    }
-
-    /**
-     * 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) {
-        return asCondVar(condition).getWaitQueueLength();
-    }
-
-    /**
-     * 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 getWaitingThreads(Condition condition) {
-        return asCondVar(condition).getWaitingThreads();
-    }
-
-    /**
-     * Returns a string identifying this lock, as well as its lock
-     * state.  The state, in brackets, includes either the String
-     * &quot;Unlocked&quot; or the String &quot;Locked by&quot;
-     * 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 o = getOwner();
-
-        return super.toString() +
-        ((o == null) ? "[Unlocked]" : ("[Locked by thread " + o.getName() +
-        "]"));
-    }
-
-    private CondVar asCondVar(Condition condition) {
-        if (condition == null) {
-            throw new NullPointerException();
-        }
-
-        if (!(condition instanceof CondVar)) {
-            throw new IllegalArgumentException("not owner");
-        }
-
-        CondVar condVar = (CondVar) condition;
-
-        if (condVar.lock != this) {
-            throw new IllegalArgumentException("not owner");
-        }
-
-        return condVar;
-    }
-
-    static abstract class Sync implements java.io.Serializable {
-        private static final long serialVersionUID = -5179523762034025860L;
-        protected transient Thread owner_ = null;
-        protected transient int holds_ = 0;
-
-        protected Sync() {
-        }
-
-        public abstract void lock();
-
-        public abstract void lockInterruptibly() throws InterruptedException;
-
-        final void incHolds() {
-            int nextHolds = ++holds_;
-
-            if (nextHolds < 0) {
-                throw new Error("Maximum lock count exceeded");
-            }
-
-            holds_ = nextHolds;
-        }
-
-        public boolean tryLock() {
-            Thread caller = Thread.currentThread();
-
-            synchronized (this) {
-                if (owner_ == null) {
-                    owner_ = caller;
-                    holds_ = 1;
-
-                    return true;
-                } else if (caller == owner_) {
-                    incHolds();
-
-                    return true;
-                }
-            }
-
-            return false;
-        }
-
-        public abstract boolean tryLock(long nanos) throws InterruptedException;
-
-        public abstract void unlock();
-
-        public synchronized int getHoldCount() {
-            return isHeldByCurrentThread() ? holds_ : 0;
-        }
-
-        public synchronized boolean isHeldByCurrentThread() {
-            return (holds_ > 0) && (Thread.currentThread() == owner_);
-        }
-
-        public synchronized boolean isLocked() {
-            return owner_ != null;
-        }
-
-        public abstract boolean isFair();
+        public abstract boolean isFair();
 
         protected synchronized Thread getOwner() {
             return owner_;
@@ -699,85 +152,63 @@
     final static class NonfairSync extends Sync {
         private static final long serialVersionUID = 7316153563782823691L;
 
-        NonfairSync() {
-        }
+        NonfairSync() {}
 
         public void lock() {
             Thread caller = Thread.currentThread();
-
             synchronized (this) {
                 if (owner_ == null) {
                     owner_ = caller;
                     holds_ = 1;
-
                     return;
                 } else if (caller == owner_) {
                     incHolds();
-
                     return;
                 } else {
                     boolean wasInterrupted = Thread.interrupted();
-
                     try {
                         while (true) {
                             try {
                                 wait();
                             } catch (InterruptedException e) {
                                 wasInterrupted = true;
-
                                 // no need to notify; if we were signalled, we
                                 // will act as signalled, ignoring the
                                 // interruption
                             }
-
                             if (owner_ == null) {
                                 owner_ = caller;
                                 holds_ = 1;
-
                                 return;
                             }
                         }
-                    } finally {
-                        if (wasInterrupted) {
-                            Thread.currentThread().interrupt();
-                        }
+                    }
+                    finally {
+                        if (wasInterrupted) Thread.currentThread().interrupt();
                     }
                 }
             }
         }
 
         public void lockInterruptibly() throws InterruptedException {
-            if (Thread.interrupted()) {
-                throw new InterruptedException();
-            }
-
+            if (Thread.interrupted()) throw new InterruptedException();
             Thread caller = Thread.currentThread();
-
             synchronized (this) {
                 if (owner_ == null) {
                     owner_ = caller;
                     holds_ = 1;
-
                     return;
                 } else if (caller == owner_) {
                     incHolds();
-
                     return;
                 } else {
                     try {
-                        do {
-                            wait();
-                        } while (owner_ != null);
-
+                        do { wait(); } while (owner_ != null);
                         owner_ = caller;
                         holds_ = 1;
-
                         return;
                     } catch (InterruptedException ex) {
-                        if (owner_ == null) {
-                            notify();
-                        }
-
+                        if (owner_ == null) notify();
                         throw ex;
                     }
                 }
@@ -785,53 +216,39 @@
         }
 
         public boolean tryLock(long nanos) throws InterruptedException {
-            if (Thread.interrupted()) {
-                throw new InterruptedException();
-            }
-
+            if (Thread.interrupted()) throw new InterruptedException();
             Thread caller = Thread.currentThread();
 
             synchronized (this) {
                 if (owner_ == null) {
                     owner_ = caller;
                     holds_ = 1;
-
                     return true;
                 } else if (caller == owner_) {
                     incHolds();
-
                     return true;
-                } else if (nanos <= 0) {
+                } else if (nanos <= 0)
                     return false;
-                } else {
+                else {
                     long deadline = Utils.nanoTime() + nanos;
-
                     try {
-                        for (;;) {
+                        for (; ; ) {
                             TimeUnit.NANOSECONDS.timedWait(this, nanos);
-
                             if (caller == owner_) {
                                 incHolds();
-
                                 return true;
                             } else if (owner_ == null) {
                                 owner_ = caller;
                                 holds_ = 1;
-
                                 return true;
                             } else {
                                 nanos = deadline - Utils.nanoTime();
-
-                                if (nanos <= 0) {
+                                if (nanos <= 0)
                                     return false;
-                                }
                             }
                         }
                     } catch (InterruptedException ex) {
-                        if (owner_ == null) {
-                            notify();
-                        }
-
+                        if (owner_ == null) notify();
                         throw ex;
                     }
                 }
@@ -839,9 +256,8 @@
         }
 
         public synchronized void unlock() {
-            if (Thread.currentThread() != owner_) {
+            if (Thread.currentThread() != owner_)
                 throw new IllegalMonitorStateException("Not owner");
-            }
 
             if (--holds_ == 0) {
                 owner_ = null;
@@ -856,140 +272,103 @@
 
     final static class FairSync extends Sync implements WaitQueue.QueuedSync {
         private static final long serialVersionUID = -3000897897090466540L;
+
         private transient WaitQueue wq_ = new FIFOWaitQueue();
 
-        FairSync() {
-        }
+        FairSync() {}
 
         public synchronized boolean recheck(WaitQueue.WaitNode node) {
             Thread caller = Thread.currentThread();
-
             if (owner_ == null) {
                 owner_ = caller;
                 holds_ = 1;
-
                 return true;
             } else if (caller == owner_) {
                 incHolds();
-
                 return true;
             }
-
             wq_.insert(node);
-
             return false;
         }
 
         public synchronized void takeOver(WaitQueue.WaitNode node) {
-            // assert (holds_ == 1 && owner_ == Thread.currentThread()
+            // assert(holds_ == 1 && owner_ == Thread.currentThread()
             owner_ = node.getOwner();
         }
 
         public void lock() {
             Thread caller = Thread.currentThread();
-
             synchronized (this) {
                 if (owner_ == null) {
                     owner_ = caller;
                     holds_ = 1;
-
                     return;
                 } else if (caller == owner_) {
                     incHolds();
-
                     return;
                 }
             }
-
             WaitQueue.WaitNode n = new WaitQueue.WaitNode();
             n.doWaitUninterruptibly(this);
         }
 
         public void lockInterruptibly() throws InterruptedException {
-            if (Thread.interrupted()) {
-                throw new InterruptedException();
-            }
-
+            if (Thread.interrupted()) throw new InterruptedException();
             Thread caller = Thread.currentThread();
-
             synchronized (this) {
                 if (owner_ == null) {
                     owner_ = caller;
                     holds_ = 1;
-
                     return;
                 } else if (caller == owner_) {
                     incHolds();
-
                     return;
                 }
             }
-
             WaitQueue.WaitNode n = new WaitQueue.WaitNode();
             n.doWait(this);
         }
 
         public boolean tryLock(long nanos) throws InterruptedException {
-            if (Thread.interrupted()) {
-                throw new InterruptedException();
-            }
-
+            if (Thread.interrupted()) throw new InterruptedException();
             Thread caller = Thread.currentThread();
-
             synchronized (this) {
                 if (owner_ == null) {
                     owner_ = caller;
                     holds_ = 1;
-
                     return true;
                 } else if (caller == owner_) {
                     incHolds();
-
                     return true;
                 }
             }
-
             WaitQueue.WaitNode n = new WaitQueue.WaitNode();
-
             return n.doTimedWait(this, nanos);
         }
 
         protected synchronized WaitQueue.WaitNode getSignallee(Thread caller) {
-            if (caller != owner_) {
+            if (caller != owner_)
                 throw new IllegalMonitorStateException("Not owner");
-            }
-
-            // assert (holds_ > 0)
+            // assert(holds_ > 0)
             if (holds_ >= 2) { // current thread will keep the lock
                 --holds_;
-
                 return null;
             }
-
-            // assert (holds_ == 1)
+            // assert(holds_ == 1)
             WaitQueue.WaitNode w = wq_.extract();
-
             if (w == null) { // if none, clear for new arrivals
                 owner_ = null;
                 holds_ = 0;
             }
-
             return w;
         }
 
         public void unlock() {
             Thread caller = Thread.currentThread();
-
             for (;;) {
                 WaitQueue.WaitNode w = getSignallee(caller);
-
-                if (w == null) {
-                    return; // no one to signal
-                }
-
-                if (w.signal(this)) {
-                    return; // notify if still waiting, or skip
-                }
+                if (w == null) return;  // no one to signal
+                if (w.signal(this)) return; // notify if still waiting, or skip
             }
         }
 
@@ -1014,12 +393,453 @@
         }
 
         private void readObject(java.io.ObjectInputStream in)
-            throws java.io.IOException, ClassNotFoundException {
+                throws java.io.IOException, ClassNotFoundException {
             in.defaultReadObject();
-
             synchronized (this) {
                 wq_ = new FIFOWaitQueue();
             }
         }
+    }
+
+    /**
+     * 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)? (Sync)new FairSync() : new NonfairSync();
+    }
+
+    /**
+     * Acquires the lock.
+     *  Acquires the lock if it is not held by another thread and returns
+     * immediately, setting the lock hold count to one.
+     *  If the current thread
+     * already holds the lock then the hold count is incremented by one and
+     * the method returns immediately.
+     *  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}.
+     *  Acquires the lock if it is not held by another thread and returns
+     * immediately, setting the lock hold count to one.
+     *  If the current thread already holds this lock then the hold count
+     * is incremented by one and the method returns immediately.
+     *  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>
+     *  If the lock is acquired by the current thread then the lock hold
+     * count is set to one.
+     *  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.
+     *  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.lockInterruptibly();
+    }
+
+    /**
+     * Acquires the lock only if it is not held by another thread at the time
+     * of invocation.
+     *  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 &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).
+     *   If the current thread
+     * already holds this lock then the hold count is incremented by one and
+     * the method returns <tt>true</tt>.
+     *  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.tryLock();
+    }
+
+    /**
+     * 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}.
+     *  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>
+     *  If the current thread
+     * already holds this lock then the hold count is incremented by one and
+     * the method returns <tt>true</tt>.
+     *  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>
+     *  If the lock is acquired then the value <tt>true</tt> is returned and
+     * the lock hold count is set to one.
+     *  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.
+     *  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.
+     *  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.tryLock(unit.toNanos(timeout));
+    }
+
+    /**
+     * Attempts to release this lock.
+     *  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.unlock();
+    }
+
+    /**
+     * Returns a {@link Condition} instance for use with this
+     * {@link Lock} instance.
+     *  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 isFair() ? new FIFOCondVar(this) : new CondVar(this);
+    }
+
+    /**
+     * Queries the number of holds on this 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.
+     *  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.
+     *  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>
+     *  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.isHeldByCurrentThread();
+    }
+
+    /**
+     * 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.isFair();
+    }
+
+    /**
+     * <tt>null</tt> 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 <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 this lock. 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 lock. 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 lock. 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 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 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) {
+        return asCondVar(condition).hasWaiters();
+    }
+
+    /**
+     * 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) {
+        return asCondVar(condition).getWaitQueueLength();
+    }
+
+    /**
+     * 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 getWaitingThreads(Condition condition) {
+        return asCondVar(condition).getWaitingThreads();
+    }
+
+    /**
+     * Returns a string identifying this lock, as well as its lock
+     * state. The state, in brackets, includes either the String
+     * &quot;Unlocked&quot; or the String &quot;Locked by&quot;
+     * 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 o = getOwner();
+        return super.toString() + ((o == null) ? "[Unlocked]"
+            : "[Locked by thread " + o.getName() + "]");
+    }
+
+    private CondVar asCondVar(Condition condition) {
+        if (condition == null)
+            throw new NullPointerException();
+        if (!(condition instanceof CondVar))
+            throw new IllegalArgumentException("not owner");
+        CondVar condVar = (CondVar)condition;
+        if (condVar.lock != this)
+            throw new IllegalArgumentException("not owner");
+        return condVar;
     }
 }

Modified: incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/TimeUnit.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/TimeUnit.java?rev=418401&r1=418400&r2=418401&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/TimeUnit.java (original)
+++ incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/util/concurrent/TimeUnit.java Fri Jun 30 15:37:18 2006
@@ -1,19 +1,15 @@
 /*
  * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
+ *  Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *  Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 /*
  * Written by Doug Lea with assistance from members of JCP JSR-166
  * Expert Group and released to the public domain, as explained at
@@ -21,337 +17,133 @@
  */
 package org.apache.openjpa.lib.util.concurrent;
 
-
 /**
  * A <tt>TimeUnit</tt> represents time durations at a given unit of
  * granularity and provides utility methods to convert across units,
- * and to perform timing and delay operations in these units.  A
+ * and to perform timing and delay operations in these units. A
  * <tt>TimeUnit</tt> does not maintain time information, but only
  * helps organize and use time representations that may be maintained
- * separately across various contexts.  A nanosecond is defined as one
+ * separately across various contexts. A nanosecond is defined as one
  * thousandth of a microsecond, a microsecond as one thousandth of a
  * millisecond, a millisecond as one thousandth of a second, a minute
- * as sixty seconds, an hour as sixty minutes, and a day as twenty four
- * hours.
- *
- * <p>A <tt>TimeUnit</tt> is mainly used to inform time-based methods
+ * as sixty seconds, an hour as sixty minutes, and a day as twenty four hours.
+ *  A <tt>TimeUnit</tt> is mainly used to inform time-based methods
  * how a given timing parameter should be interpreted. For example,
  * the following code will timeout in 50 milliseconds if the {@link
  * edu.emory.mathcs.backport.java.util.concurrent.locks.Lock lock} is not
  * available:
- *
- * <pre>
- * Lock lock = ...;
- * if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
- * </pre>
- * while this code will timeout in 50 seconds:
- * <pre>
- * Lock lock = ...;
- * if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ...
+ * 
+ * <pre> Lock lock = ...; if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
+ * </pre> while this code will timeout in 50 seconds:
+ * <pre> Lock lock = ...; if ( lock.tryLock(50L, TimeUnit.SECONDS) ) ...
  * </pre>
- *
- * Note however, that there is no guarantee that a particular timeout
+ *  Note however, that there is no guarantee that a particular timeout
  * implementation will be able to notice the passage of time at the
  * same granularity as the given <tt>TimeUnit</tt>.
- *
+ * 
  * @since 1.5
  * @author Doug Lea
  */
 public abstract class TimeUnit implements java.io.Serializable {
-    public static final TimeUnit NANOSECONDS = new TimeUnit(0, "NANOSECONDS") {
-            private final static long serialVersionUID = 535148490883208361L;
 
-            public long toNanos(long d) {
-                return d;
-            }
-
-            public long toMicros(long d) {
-                return d / (C1 / C0);
-            }
-
-            public long toMillis(long d) {
-                return d / (C2 / C0);
-            }
-
-            public long toSeconds(long d) {
-                return d / (C3 / C0);
-            }
-
-            public long toMinutes(long d) {
-                return d / (C4 / C0);
-            }
-
-            public long toHours(long d) {
-                return d / (C5 / C0);
-            }
-
-            public long toDays(long d) {
-                return d / (C6 / C0);
-            }
-
-            public long convert(long d, TimeUnit u) {
-                return u.toNanos(d);
-            }
-
-            int excessNanos(long d, long m) {
-                return (int) (d - (m * C2));
-            }
-        };
-
-    public static final TimeUnit MICROSECONDS = new TimeUnit(1, "MICROSECONDS") {
-            private final static long serialVersionUID = 2185906575929579108L;
-
-            public long toNanos(long d) {
-                return x(d, C1 / C0, MAX / (C1 / C0));
-            }
-
-            public long toMicros(long d) {
-                return d;
-            }
-
-            public long toMillis(long d) {
-                return d / (C2 / C1);
-            }
-
-            public long toSeconds(long d) {
-                return d / (C3 / C1);
-            }
-
-            public long toMinutes(long d) {
-                return d / (C4 / C1);
-            }
-
-            public long toHours(long d) {
-                return d / (C5 / C1);
-            }
-
-            public long toDays(long d) {
-                return d / (C6 / C1);
-            }
-
-            public long convert(long d, TimeUnit u) {
-                return u.toMicros(d);
-            }
-
-            int excessNanos(long d, long m) {
-                return (int) ((d * C1) - (m * C2));
-            }
-        };
-
-    public static final TimeUnit MILLISECONDS = new TimeUnit(2, "MILLISECONDS") {
-            private final static long serialVersionUID = 9032047794123325184L;
-
-            public long toNanos(long d) {
-                return x(d, C2 / C0, MAX / (C2 / C0));
-            }
-
-            public long toMicros(long d) {
-                return x(d, C2 / C1, MAX / (C2 / C1));
-            }
-
-            public long toMillis(long d) {
-                return d;
-            }
-
-            public long toSeconds(long d) {
-                return d / (C3 / C2);
-            }
-
-            public long toMinutes(long d) {
-                return d / (C4 / C2);
-            }
-
-            public long toHours(long d) {
-                return d / (C5 / C2);
-            }
-
-            public long toDays(long d) {
-                return d / (C6 / C2);
-            }
-
-            public long convert(long d, TimeUnit u) {
-                return u.toMillis(d);
-            }
-
-            int excessNanos(long d, long m) {
-                return 0;
-            }
-        };
+    public static final TimeUnit NANOSECONDS = new TimeUnit(0, "NANOSECONDS") {
+        private final static long serialVersionUID = 535148490883208361L;
+        public long toNanos(long d)   { return d; }
+        public long toMicros(long d)  { return d/(C1/C0); }
+        public long toMillis(long d)  { return d/(C2/C0); }
+        public long toSeconds(long d) { return d/(C3/C0); }
+        public long toMinutes(long d) { return d/(C4/C0); }
+        public long toHours(long d)   { return d/(C5/C0); }
+        public long toDays(long d)    { return d/(C6/C0); }
+        public long convert(long d, TimeUnit u) { return u.toNanos(d); }
+        int excessNanos(long d, long m) { return(int)(d - (m*C2)); }
+    };
+
+    public static final TimeUnit MICROSECONDS = new TimeUnit(1, "MICROSECONDS"){
+        private final static long serialVersionUID = 2185906575929579108L;
+        public long toNanos(long d)   { return x(d, C1/C0, MAX/(C1/C0)); }
+        public long toMicros(long d)  { return d; }
+        public long toMillis(long d)  { return d/(C2/C1); }
+        public long toSeconds(long d) { return d/(C3/C1); }
+        public long toMinutes(long d) { return d/(C4/C1); }
+        public long toHours(long d)   { return d/(C5/C1); }
+        public long toDays(long d)    { return d/(C6/C1); }
+        public long convert(long d, TimeUnit u) { return u.toMicros(d); }
+        int excessNanos(long d, long m) { return(int)((d*C1) - (m*C2)); }
+    };
+
+    public static final TimeUnit MILLISECONDS = new TimeUnit(2, "MILLISECONDS"){
+        private final static long serialVersionUID = 9032047794123325184L;
+        public long toNanos(long d)   { return x(d, C2/C0, MAX/(C2/C0)); }
+        public long toMicros(long d)  { return x(d, C2/C1, MAX/(C2/C1)); }
+        public long toMillis(long d)  { return d; }
+        public long toSeconds(long d) { return d/(C3/C2); }
+        public long toMinutes(long d) { return d/(C4/C2); }
+        public long toHours(long d)   { return d/(C5/C2); }
+        public long toDays(long d)    { return d/(C6/C2); }
+        public long convert(long d, TimeUnit u) { return u.toMillis(d); }
+        int excessNanos(long d, long m) { return 0; }
+    };
 
     public static final TimeUnit SECONDS = new TimeUnit(3, "SECONDS") {
-            private final static long serialVersionUID = 227755028449378390L;
-
-            public long toNanos(long d) {
-                return x(d, C3 / C0, MAX / (C3 / C0));
-            }
-
-            public long toMicros(long d) {
-                return x(d, C3 / C1, MAX / (C3 / C1));
-            }
-
-            public long toMillis(long d) {
-                return x(d, C3 / C2, MAX / (C3 / C2));
-            }
-
-            public long toSeconds(long d) {
-                return d;
-            }
-
-            public long toMinutes(long d) {
-                return d / (C4 / C3);
-            }
-
-            public long toHours(long d) {
-                return d / (C5 / C3);
-            }
-
-            public long toDays(long d) {
-                return d / (C6 / C3);
-            }
-
-            public long convert(long d, TimeUnit u) {
-                return u.toSeconds(d);
-            }
-
-            int excessNanos(long d, long m) {
-                return 0;
-            }
-        };
+        private final static long serialVersionUID = 227755028449378390L;
+        public long toNanos(long d)   { return x(d, C3/C0, MAX/(C3/C0)); }
+        public long toMicros(long d)  { return x(d, C3/C1, MAX/(C3/C1)); }
+        public long toMillis(long d)  { return x(d, C3/C2, MAX/(C3/C2)); }
+        public long toSeconds(long d) { return d; }
+        public long toMinutes(long d) { return d/(C4/C3); }
+        public long toHours(long d)   { return d/(C5/C3); }
+        public long toDays(long d)    { return d/(C6/C3); }
+        public long convert(long d, TimeUnit u) { return u.toSeconds(d); }
+        int excessNanos(long d, long m) { return 0; }
+    };
 
     public static final TimeUnit MINUTES = new TimeUnit(4, "MINUTES") {
-            private final static long serialVersionUID = 1827351566402609187L;
-
-            public long toNanos(long d) {
-                return x(d, C4 / C0, MAX / (C4 / C0));
-            }
-
-            public long toMicros(long d) {
-                return x(d, C4 / C1, MAX / (C4 / C1));
-            }
-
-            public long toMillis(long d) {
-                return x(d, C4 / C2, MAX / (C4 / C2));
-            }
-
-            public long toSeconds(long d) {
-                return x(d, C4 / C3, MAX / (C4 / C3));
-            }
-
-            public long toMinutes(long d) {
-                return d;
-            }
-
-            public long toHours(long d) {
-                return d / (C5 / C4);
-            }
-
-            public long toDays(long d) {
-                return d / (C6 / C4);
-            }
-
-            public long convert(long d, TimeUnit u) {
-                return u.toMinutes(d);
-            }
-
-            int excessNanos(long d, long m) {
-                return 0;
-            }
-        };
+        private final static long serialVersionUID = 1827351566402609187L;
+        public long toNanos(long d)   { return x(d, C4/C0, MAX/(C4/C0)); }
+        public long toMicros(long d)  { return x(d, C4/C1, MAX/(C4/C1)); }
+        public long toMillis(long d)  { return x(d, C4/C2, MAX/(C4/C2)); }
+        public long toSeconds(long d) { return x(d, C4/C3, MAX/(C4/C3)); }
+        public long toMinutes(long d) { return d; }
+        public long toHours(long d)   { return d/(C5/C4); }
+        public long toDays(long d)    { return d/(C6/C4); }
+        public long convert(long d, TimeUnit u) { return u.toMinutes(d); }
+        int excessNanos(long d, long m) { return 0; }
+    };
 
     public static final TimeUnit HOURS = new TimeUnit(5, "HOURS") {
-            private final static long serialVersionUID = -6438436134732089810L;
-
-            public long toNanos(long d) {
-                return x(d, C5 / C0, MAX / (C5 / C0));
-            }
-
-            public long toMicros(long d) {
-                return x(d, C5 / C1, MAX / (C5 / C1));
-            }
-
-            public long toMillis(long d) {
-                return x(d, C5 / C2, MAX / (C5 / C2));
-            }
-
-            public long toSeconds(long d) {
-                return x(d, C5 / C3, MAX / (C5 / C3));
-            }
-
-            public long toMinutes(long d) {
-                return x(d, C5 / C4, MAX / (C5 / C4));
-            }
-
-            public long toHours(long d) {
-                return d;
-            }
-
-            public long toDays(long d) {
-                return d / (C6 / C5);
-            }
-
-            public long convert(long d, TimeUnit u) {
-                return u.toHours(d);
-            }
-
-            int excessNanos(long d, long m) {
-                return 0;
-            }
-        };
+        private final static long serialVersionUID = -6438436134732089810L;
+        public long toNanos(long d)   { return x(d, C5/C0, MAX/(C5/C0)); }
+        public long toMicros(long d)  { return x(d, C5/C1, MAX/(C5/C1)); }
+        public long toMillis(long d)  { return x(d, C5/C2, MAX/(C5/C2)); }
+        public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
+        public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
+        public long toHours(long d)   { return d; }
+        public long toDays(long d)    { return d/(C6/C5); }
+        public long convert(long d, TimeUnit u) { return u.toHours(d); }
+        int excessNanos(long d, long m) { return 0; }
+    };
 
     public static final TimeUnit DAYS = new TimeUnit(6, "DAYS") {
-            private final static long serialVersionUID = 567463171959674600L;
-
-            public long toNanos(long d) {
-                return x(d, C6 / C0, MAX / (C6 / C0));
-            }
-
-            public long toMicros(long d) {
-                return x(d, C6 / C1, MAX / (C6 / C1));
-            }
-
-            public long toMillis(long d) {
-                return x(d, C6 / C2, MAX / (C6 / C2));
-            }
-
-            public long toSeconds(long d) {
-                return x(d, C6 / C3, MAX / (C6 / C3));
-            }
-
-            public long toMinutes(long d) {
-                return x(d, C6 / C4, MAX / (C6 / C4));
-            }
-
-            public long toHours(long d) {
-                return x(d, C6 / C5, MAX / (C6 / C5));
-            }
-
-            public long toDays(long d) {
-                return d;
-            }
-
-            public long convert(long d, TimeUnit u) {
-                return u.toDays(d);
-            }
-
-            int excessNanos(long d, long m) {
-                return 0;
-            }
-        };
+        private final static long serialVersionUID = 567463171959674600L;
+        public long toNanos(long d)   { return x(d, C6/C0, MAX/(C6/C0)); }
+        public long toMicros(long d)  { return x(d, C6/C1, MAX/(C6/C1)); }
+        public long toMillis(long d)  { return x(d, C6/C2, MAX/(C6/C2)); }
+        public long toSeconds(long d) { return x(d, C6/C3, MAX/(C6/C3)); }
+        public long toMinutes(long d) { return x(d, C6/C4, MAX/(C6/C4)); }
+        public long toHours(long d)   { return x(d, C6/C5, MAX/(C6/C5)); }
+        public long toDays(long d)    { return d; }
+        public long convert(long d, TimeUnit u) { return u.toDays(d); }
+        int excessNanos(long d, long m) { return 0; }
+    };
 
     private static final TimeUnit[] values = new TimeUnit[] {
-            NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS,
-            DAYS
-        };
+        NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS
+    };
 
-    // Handy constants for conversion methods
-    static final long C0 = 1;
-    static final long C1 = C0 * 1000;
-    static final long C2 = C1 * 1000;
-    static final long C3 = C2 * 1000;
-    static final long C4 = C3 * 60;
-    static final long C5 = C4 * 60;
-    static final long C6 = C5 * 24;
-    static final long MAX = Long.MAX_VALUE;
+    public static TimeUnit[] values() {
+        return(TimeUnit[])values.clone();
+    }
 
     /**
      * The index of this unit. This value is no longer used in this
@@ -361,47 +153,46 @@
     private final int index;
 
     /** name of this unit */
-    private final String name;
+ private final String name;
 
-    /** Internal constructor */
-    TimeUnit(int index, String name) {
+    /** Internal constructor */ TimeUnit(int index, String name) {
         this.index = index;
         this.name = name;
     }
 
-    public static TimeUnit[] values() {
-        return (TimeUnit[]) values.clone();
-    }
+    // Handy constants for conversion methods
+    static final long C0 = 1;
+    static final long C1 = C0 * 1000;
+    static final long C2 = C1 * 1000;
+    static final long C3 = C2 * 1000;
+    static final long C4 = C3 * 60;
+    static final long C5 = C4 * 60;
+    static final long C6 = C5 * 24;
+
+    static final long MAX = Long.MAX_VALUE;
 
     /**
      * Scale d by m, checking for overflow.
      * This has a short name to make above code more readable.
      */
     static long x(long d, long m, long over) {
-        if (d > over) {
-            return Long.MAX_VALUE;
-        }
-
-        if (d < -over) {
-            return Long.MIN_VALUE;
-        }
-
+        if (d >  over) return Long.MAX_VALUE;
+        if (d < -over) return Long.MIN_VALUE;
         return d * m;
     }
 
     /**
      * Convert the given time duration in the given unit to this
-     * unit.  Conversions from finer to coarser granularities
+     * unit. Conversions from finer to coarser granularities
      * truncate, so lose precision. For example converting
      * <tt>999</tt> milliseconds to seconds results in
      * <tt>0</tt>. Conversions from coarser to finer granularities
      * with arguments that would numerically overflow saturate to
      * <tt>Long.MIN_VALUE</tt> if negative or <tt>Long.MAX_VALUE</tt>
      * if positive.
-     *
-     * <p>For example, to convert 10 minutes to milliseconds, use:
+     *  For example, to convert 10 minutes to milliseconds, use:
      * <tt>TimeUnit.MILLISECONDS.convert(10L, TimeUnit.MINUTES)</tt>
-     *
+     * 
      * @param sourceDuration the time duration in the given <tt>sourceUnit</tt>
      * @param sourceUnit the unit of the <tt>sourceDuration</tt> argument
      * @return the converted duration in this unit,
@@ -482,8 +273,7 @@
     public abstract long toDays(long duration);
 
     /**
-     * Utility to compute the excess-nanosecond argument to wait,
-     * sleep, join.
+     * Utility to compute the excess-nanosecond argument to wait, sleep, join.
      * @param d the duration
      * @param m the number of milliseconds
      * @return the number of nanoseconds
@@ -494,27 +284,21 @@
      * Performs a timed <tt>Object.wait</tt> using this time unit.
      * This is a convenience method that converts timeout arguments
      * into the form required by the <tt>Object.wait</tt> method.
-     *
-     * <p>For example, you could implement a blocking <tt>poll</tt>
-     * method (see {@link BlockingQueue#poll BlockingQueue.poll})
-     * using:
-     *
-     * <pre>
-         * public synchronized Object poll(long timeout, TimeUnit unit)
-         *    throws InterruptedException {
-     *    while (empty) {
-     *      unit.timedWait(this, timeout);
-     *      ...
-     *    }
-     *  }</pre>
-     *
+     *  For example, you could implement a blocking <tt>poll</tt>
+     * method(see {@link BlockingQueue#poll BlockingQueue.poll}) using:
+     * 
+     * <pre> public synchronized Object poll(long timeout, TimeUnit unit)
+     * throws InterruptedException { while (empty) {
+     * unit.timedWait(this, timeout); ... } }</pre>
+     * 
      * @param obj the object to wait on
      * @param timeout the maximum time to wait. If less than
      * or equal to zero, do not wait at all.
      * @throws InterruptedException if interrupted while waiting.
      * @see java.lang.Object#wait(long, int)
      */
-    public void timedWait(Object obj, long timeout) throws InterruptedException {
+    public void timedWait(Object obj, long timeout)
+        throws InterruptedException {
         if (timeout > 0) {
             long ms = toMillis(timeout);
             int ns = excessNanos(timeout, ms);