You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by hi...@apache.org on 2009/07/28 11:30:48 UTC

svn commit: r798469 [20/28] - in /harmony/enhanced/classlib/branches/java6: ./ depends/build/platform/ depends/files/ depends/jars/ depends/manifests/icu4j_4.0/ depends/manifests/icu4j_4.2.1/ depends/manifests/icu4j_4.2.1/META-INF/ make/ modules/access...

Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java Tue Jul 28 09:30:33 2009
@@ -19,32 +19,60 @@
  *
  * <p> This class does not impose a reader or writer preference
  * ordering for lock access.  However, it does support an optional
- * <em>fairness</em> policy.  When constructed as fair, threads
- * contend for entry using an approximately arrival-order policy. When
- * the write lock is released either the longest-waiting single writer
- * will be assigned the write lock, or if there is a reader waiting
- * longer than any writer, the set of readers will be assigned the
- * read lock.  When constructed as non-fair, the order of entry to the
- * lock need not be in arrival order.  In either case, if readers are
- * active and a writer enters the lock then no subsequent readers will
- * be granted the read lock until after that writer has acquired and
- * released the write lock.
- * 
+ * <em>fairness</em> policy.
+ *
+ * <dl>
+ * <dt><b><i>Non-fair mode (default)</i></b>
+ * <dd>When constructed as non-fair (the default), the order of entry
+ * to the read and write lock is unspecified, subject to reentrancy
+ * constraints.  A nonfair lock that is continuously contended may
+ * indefinitely postpone one or more reader or writer threads, but
+ * will normally have higher throughput than a fair lock.
+ * <p>
+ *
+ * <dt><b><i>Fair mode</i></b>
+ * <dd> When constructed as fair, threads contend for entry using an
+ * approximately arrival-order policy. When the currently held lock
+ * is released either the longest-waiting single writer thread will
+ * be assigned the write lock, or if there is a group of reader threads
+ * waiting longer than all waiting writer threads, that group will be
+ * assigned the read lock.
+ *
+ * <p>A thread that tries to acquire a fair read lock (non-reentrantly)
+ * will block if either the write lock is held, or there is a waiting
+ * writer thread. The thread will not acquire the read lock until
+ * after the oldest currently waiting writer thread has acquired and
+ * released the write lock. Of course, if a waiting writer abandons
+ * its wait, leaving one or more reader threads as the longest waiters
+ * in the queue with the write lock free, then those readers will be
+ * assigned the read lock.
+ *
+ * <p>A thread that tries to acquire a fair write lock (non-reentrantly)
+ * will block unless both the read lock and write lock are free (which
+ * implies there are no waiting threads).  (Note that the non-blocking
+ * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
+ * do not honor this fair setting and will acquire the lock if it is
+ * possible, regardless of waiting threads.)
+ * <p>
+ * </dl>
+ *
  * <li><b>Reentrancy</b>
+ *
  * <p>This lock allows both readers and writers to reacquire read or
- * write locks in the style of a {@link ReentrantLock}. Readers are not
- * allowed until all write locks held by the writing thread have been
- * released.  
- * <p>Additionally, a writer can acquire the read lock - but not vice-versa.
- * Among other applications, reentrancy can be useful when
- * write locks are held during calls or callbacks to methods that
- * perform reads under read locks. 
- * If a reader tries to acquire the write lock it will never succeed.
- * 
+ * write locks in the style of a {@link ReentrantLock}. Non-reentrant
+ * readers are not allowed until all write locks held by the writing
+ * thread have been released.
+ *
+ * <p>Additionally, a writer can acquire the read lock, but not
+ * vice-versa.  Among other applications, reentrancy can be useful
+ * when write locks are held during calls or callbacks to methods that
+ * perform reads under read locks.  If a reader tries to acquire the
+ * write lock it will never succeed.
+ *
  * <li><b>Lock downgrading</b>
  * <p>Reentrancy also allows downgrading from the write lock to a read lock,
  * by acquiring the write lock, then the read lock and then releasing the
- * write lock. However, upgrading from a read lock to the write lock, is
+ * write lock. However, upgrading from a read lock to the write lock is
  * <b>not</b> possible.
  *
  * <li><b>Interruption of lock acquisition</b>
@@ -53,96 +81,105 @@
  *
  * <li><b>{@link Condition} support</b>
  * <p>The write lock provides a {@link Condition} implementation that
- * behaves in the same way, with respect to the write lock, as the 
+ * behaves in the same way, with respect to the write lock, as the
  * {@link Condition} implementation provided by
  * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
  * This {@link Condition} can, of course, only be used with the write lock.
+ *
  * <p>The read lock does not support a {@link Condition} and
- * <tt>readLock().newCondition()</tt> throws 
- * <tt>UnsupportedOperationException</tt>.
+ * {@code readLock().newCondition()} throws
+ * {@code UnsupportedOperationException}.
  *
  * <li><b>Instrumentation</b>
- * <P> This class supports methods to determine whether locks
+ * <p>This class supports methods to determine whether locks
  * are held or contended. These methods are designed for monitoring
  * system state, not for synchronization control.
  * </ul>
  *
- * <p> Serialization of this class behaves in the same way as built-in
+ * <p>Serialization of this class behaves in the same way as built-in
  * locks: a deserialized lock is in the unlocked state, regardless of
  * its state when serialized.
  *
- * <p><b>Sample usages</b>. Here is a code sketch showing how to exploit
- * reentrancy to perform lock downgrading after updating a cache (exception
- * handling is elided for simplicity):
- * <pre>
+ * <p><b>Sample usages</b>. Here is a code sketch showing how to perform
+ * lock downgrading after updating a cache (exception handling is
+ * particularly tricky when handling multiple locks in a non-nested
+ * fashion):
+ *
+ * <pre> {@code
  * class CachedData {
  *   Object data;
  *   volatile boolean cacheValid;
- *   ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+ *   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  *
  *   void processCachedData() {
  *     rwl.readLock().lock();
  *     if (!cacheValid) {
- *        // upgrade lock manually
- *        rwl.readLock().unlock();   // must unlock first to obtain writelock
+ *        // Must release read lock before acquiring write lock
+ *        rwl.readLock().unlock();
  *        rwl.writeLock().lock();
- *        if (!cacheValid) { // recheck
- *          data = ...
- *          cacheValid = true;
+ *        try {
+ *          // Recheck state because another thread might have
+ *          // acquired write lock and changed state before we did.
+ *          if (!cacheValid) {
+ *            data = ...
+ *            cacheValid = true;
+ *          }
+ *          // Downgrade by acquiring read lock before releasing write lock
+ *          rwl.readLock().lock();
+ *        } finally  {
+ *          rwl.writeLock().unlock(); // Unlock write, still hold read
  *        }
- *        // downgrade lock
- *        rwl.readLock().lock();  // reacquire read without giving up write lock
- *        rwl.writeLock().unlock(); // unlock write, still hold read
  *     }
  *
- *     use(data);
- *     rwl.readLock().unlock();
+ *     try {
+ *       use(data);
+ *     } finally {
+ *       rwl.readLock().unlock();
+ *     }
  *   }
- * }
- * </pre>
+ * }}</pre>
  *
  * ReentrantReadWriteLocks can be used to improve concurrency in some
  * uses of some kinds of Collections. This is typically worthwhile
  * only when the collections are expected to be large, accessed by
  * more reader threads than writer threads, and entail operations with
  * overhead that outweighs synchronization overhead. For example, here
- * is a class using a TreeMap that is expected to be large and 
+ * is a class using a TreeMap that is expected to be large and
  * concurrently accessed.
  *
- * <pre>
+ * <pre>{@code
  * class RWDictionary {
- *    private final Map&lt;String, Data&gt;  m = new TreeMap&lt;String, Data&gt;();
+ *    private final Map<String, Data> m = new TreeMap<String, Data>();
  *    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  *    private final Lock r = rwl.readLock();
  *    private final Lock w = rwl.writeLock();
  *
  *    public Data get(String key) {
- *        r.lock(); try { return m.get(key); } finally { r.unlock(); }
+ *        r.lock();
+ *        try { return m.get(key); }
+ *        finally { r.unlock(); }
  *    }
  *    public String[] allKeys() {
- *        r.lock(); try { return m.keySet().toArray(); } finally { r.unlock(); }
+ *        r.lock();
+ *        try { return m.keySet().toArray(); }
+ *        finally { r.unlock(); }
  *    }
  *    public Data put(String key, Data value) {
- *        w.lock(); try { return m.put(key, value); } finally { w.unlock(); }
+ *        w.lock();
+ *        try { return m.put(key, value); }
+ *        finally { w.unlock(); }
  *    }
  *    public void clear() {
- *        w.lock(); try { m.clear(); } finally { w.unlock(); }
+ *        w.lock();
+ *        try { m.clear(); }
+ *        finally { w.unlock(); }
  *    }
- * }
- * </pre>
- * 
+ * }}</pre>
  *
  * <h3>Implementation Notes</h3>
  *
- * <p>A reentrant write lock intrinsically defines an owner and can
- * only be released by the thread that acquired it.  In contrast, in
- * this implementation, the read lock has no concept of ownership, and
- * there is no requirement that the thread releasing a read lock is
- * the same as the one that acquired it.  However, this property is
- * not guaranteed to hold in future implementations of this class.
- *
- * <p> This lock supports a maximum of 65536 recursive write locks
- * and 65536 read locks. Attempts to exceed these limits result in
+ * <p>This lock supports a maximum of 65535 recursive write locks
+ * and 65535 read locks. Attempts to exceed these limits result in
  * {@link Error} throws from locking methods.
  *
  * @since 1.5
@@ -156,26 +193,24 @@
     /** Inner class providing writelock */
     private final ReentrantReadWriteLock.WriteLock writerLock;
     /** Performs all synchronization mechanics */
-    private final Sync sync;
+    final Sync sync;
 
     /**
-     * Creates a new <tt>ReentrantReadWriteLock</tt> with
-     * default ordering properties.
+     * Creates a new {@code ReentrantReadWriteLock} with
+     * default (nonfair) ordering properties.
      */
     public ReentrantReadWriteLock() {
-        sync = new NonfairSync();
-        readerLock = new ReadLock(this);
-        writerLock = new WriteLock(this);
+        this(false);
     }
 
     /**
-     * Creates a new <tt>ReentrantReadWriteLock</tt> with
+     * Creates a new {@code ReentrantReadWriteLock} with
      * the given fairness policy.
      *
-     * @param fair true if this lock should use a fair ordering policy
+     * @param fair {@code true} if this lock should use a fair ordering policy
      */
     public ReentrantReadWriteLock(boolean fair) {
-        sync = (fair)? new FairSync() : new NonfairSync();
+        sync = fair ? new FairSync() : new NonfairSync();
         readerLock = new ReadLock(this);
         writerLock = new WriteLock(this);
     }
@@ -183,129 +218,409 @@
     public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
     public ReentrantReadWriteLock.ReadLock  readLock()  { return readerLock; }
 
-    /* 
-     * Read vs write count extraction constants and functions.
-     * Lock state is logically divided into two shorts: The lower
-     * one representing the exclusive (writer) lock hold count,
-     * and the upper the shared (reader) hold count.
-     */
-    
-    static final int SHARED_SHIFT   = 16;
-    static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
-    static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
-    
-    /** Returns the number of shared holds represented in count  */
-    static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
-    /** Returns the number of exclusive holds represented in count  */
-    static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
-
-    /** 
+    /**
      * Synchronization implementation for ReentrantReadWriteLock.
      * Subclassed into fair and nonfair versions.
      */
-    abstract static class Sync extends AbstractQueuedSynchronizer {
-        /** Current (exclusive) owner thread */
-        transient Thread owner;
+    static abstract class Sync extends AbstractQueuedSynchronizer {
+        private static final long serialVersionUID = 6317671515068378041L;
+
+        /*
+         * Read vs write count extraction constants and functions.
+         * Lock state is logically divided into two unsigned shorts:
+         * The lower one representing the exclusive (writer) lock hold count,
+         * and the upper the shared (reader) hold count.
+         */
+
+        static final int SHARED_SHIFT   = 16;
+        static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
+        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
+        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
+
+        /** Returns the number of shared holds represented in count  */
+        static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
+        /** Returns the number of exclusive holds represented in count  */
+        static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
 
         /**
-         * Perform write lock. Allows fast path in non-fair version.
+         * A counter for per-thread read hold counts.
+         * Maintained as a ThreadLocal; cached in cachedHoldCounter
          */
-        abstract void wlock();
+        static final class HoldCounter {
+            int count = 0;
+            // Use id, not reference, to avoid garbage retention
+            final long tid = Thread.currentThread().getId();
+        }
 
-        /** 
-         * Perform non-fair tryLock for write.  tryAcquire is
-         * implemented in subclasses, but both versions need nonfair
-         * try for trylock method
+        /**
+         * ThreadLocal subclass. Easiest to explicitly define for sake
+         * of deserialization mechanics.
          */
-        final boolean nonfairTryAcquire(int acquires) {
-            // mask out readlocks if called from condition methods
-            acquires = exclusiveCount(acquires);
+        static final class ThreadLocalHoldCounter
+            extends ThreadLocal<HoldCounter> {
+            public HoldCounter initialValue() {
+                return new HoldCounter();
+            }
+        }
+
+        /**
+         * The number of reentrant read locks held by current thread.
+         * Initialized only in constructor and readObject.
+         * Removed whenever a thread's read hold count drops to 0.
+         */
+        private transient ThreadLocalHoldCounter readHolds;
+
+        /**
+         * The hold count of the last thread to successfully acquire
+         * readLock. This saves ThreadLocal lookup in the common case
+         * where the next thread to release is the last one to
+         * acquire. This is non-volatile since it is just used
+         * as a heuristic, and would be great for threads to cache.
+         *
+         * <p>Can outlive the Thread for which it is caching the read
+         * hold count, but avoids garbage retention by not retaining a
+         * reference to the Thread.
+         *
+         * <p>Accessed via a benign data race; relies on the memory
+         * model's final field and out-of-thin-air guarantees.
+         */
+        private transient HoldCounter cachedHoldCounter;
+
+        /**
+         * firstReader is the first thread to have acquired the read lock.
+         * firstReaderHoldCount is firstReader's hold count.
+         *
+         * <p>More precisely, firstReader is the unique thread that last
+         * changed the shared count from 0 to 1, and has not released the
+         * read lock since then; null if there is no such thread.
+         *
+         * <p>Cannot cause garbage retention unless the thread terminated
+         * without relinquishing its read locks, since tryReleaseShared
+         * sets it to null.
+         *
+         * <p>Accessed via a benign data race; relies on the memory
+         * model's out-of-thin-air guarantees for references.
+         *
+         * <p>This allows tracking of read holds for uncontended read
+         * locks to be very cheap.
+         */
+        private transient Thread firstReader = null;
+        private transient int firstReaderHoldCount;
+
+        Sync() {
+            readHolds = new ThreadLocalHoldCounter();
+            setState(getState()); // ensures visibility of readHolds
+        }
+
+        /*
+         * Acquires and releases use the same code for fair and
+         * nonfair locks, but differ in whether/how they allow barging
+         * when queues are non-empty.
+         */
+
+        /**
+         * Returns true if the current thread, when trying to acquire
+         * the read lock, and otherwise eligible to do so, should block
+         * because of policy for overtaking other waiting threads.
+         */
+        abstract boolean readerShouldBlock();
+
+        /**
+         * Returns true if the current thread, when trying to acquire
+         * the write lock, and otherwise eligible to do so, should block
+         * because of policy for overtaking other waiting threads.
+         */
+        abstract boolean writerShouldBlock();
+
+        /*
+         * Note that tryRelease and tryAcquire can be called by
+         * Conditions. So it is possible that their arguments contain
+         * both read and write holds that are all released during a
+         * condition wait and re-established in tryAcquire.
+         */
+
+        protected final boolean tryRelease(int releases) {
+            if (!isHeldExclusively())
+                throw new IllegalMonitorStateException();
+            int nextc = getState() - releases;
+            boolean free = exclusiveCount(nextc) == 0;
+            if (free)
+                setExclusiveOwnerThread(null);
+            setState(nextc);
+            return free;
+        }
+
+        protected final boolean tryAcquire(int acquires) {
+            /*
+             * Walkthrough:
+             * 1. If read count nonzero or write count nonzero
+             *    and owner is a different thread, fail.
+             * 2. If count would saturate, fail. (This can only
+             *    happen if count is already nonzero.)
+             * 3. Otherwise, this thread is eligible for lock if
+             *    it is either a reentrant acquire or
+             *    queue policy allows it. If so, update state
+             *    and set owner.
+             */
             Thread current = Thread.currentThread();
             int c = getState();
             int w = exclusiveCount(c);
-            if (w + acquires >= SHARED_UNIT)
-                throw new Error("Maximum lock count exceeded");
-            if (c != 0 && (w == 0 || current != owner))
-                return false;
-            if (!compareAndSetState(c, c + acquires)) 
+            if (c != 0) {
+                // (Note: if c != 0 and w == 0 then shared count != 0)
+                if (w == 0 || current != getExclusiveOwnerThread())
+                    return false;
+                if (w + exclusiveCount(acquires) > MAX_COUNT)
+                    throw new Error("Maximum lock count exceeded");
+                // Reentrant acquire
+                setState(c + acquires);
+                return true;
+            }
+            if (writerShouldBlock() ||
+                !compareAndSetState(c, c + acquires))
                 return false;
-            owner = current;
+            setExclusiveOwnerThread(current);
             return true;
         }
 
-        /** 
-         * Perform nonfair tryLock for read. 
+        protected final boolean tryReleaseShared(int unused) {
+            Thread current = Thread.currentThread();
+            if (firstReader == current) {
+                // assert firstReaderHoldCount > 0;
+                if (firstReaderHoldCount == 1)
+                    firstReader = null;
+                else
+                    firstReaderHoldCount--;
+            } else {
+                HoldCounter rh = cachedHoldCounter;
+                if (rh == null || rh.tid != current.getId())
+                    rh = readHolds.get();
+                int count = rh.count;
+                if (count <= 1) {
+                    readHolds.remove();
+                    if (count <= 0)
+                        throw unmatchedUnlockException();
+                }
+                --rh.count;
+            }
+            for (;;) {
+                int c = getState();
+                int nextc = c - SHARED_UNIT;
+                if (compareAndSetState(c, nextc))
+                    // Releasing the read lock has no effect on readers,
+                    // but it may allow waiting writers to proceed if
+                    // both read and write locks are now free.
+                    return nextc == 0;
+            }
+        }
+
+        private IllegalMonitorStateException unmatchedUnlockException() {
+            return new IllegalMonitorStateException(
+                "attempt to unlock read lock, not locked by current thread");
+        }
+
+        protected final int tryAcquireShared(int unused) {
+            /*
+             * Walkthrough:
+             * 1. If write lock held by another thread, fail.
+             * 2. Otherwise, this thread is eligible for
+             *    lock wrt state, so ask if it should block
+             *    because of queue policy. If not, try
+             *    to grant by CASing state and updating count.
+             *    Note that step does not check for reentrant
+             *    acquires, which is postponed to full version
+             *    to avoid having to check hold count in
+             *    the more typical non-reentrant case.
+             * 3. If step 2 fails either because thread
+             *    apparently not eligible or CAS fails or count
+             *    saturated, chain to version with full retry loop.
+             */
+            Thread current = Thread.currentThread();
+            int c = getState();
+            if (exclusiveCount(c) != 0 &&
+                getExclusiveOwnerThread() != current)
+                return -1;
+            int r = sharedCount(c);
+            if (!readerShouldBlock() &&
+                r < MAX_COUNT &&
+                compareAndSetState(c, c + SHARED_UNIT)) {
+                if (r == 0) {
+                    firstReader = current;
+                    firstReaderHoldCount = 1;
+                } else if (firstReader == current) {
+                    firstReaderHoldCount++;
+                } else {
+                    HoldCounter rh = cachedHoldCounter;
+                    if (rh == null || rh.tid != current.getId())
+                        cachedHoldCounter = rh = readHolds.get();
+                    else if (rh.count == 0)
+                        readHolds.set(rh);
+                    rh.count++;
+                }
+                return 1;
+            }
+            return fullTryAcquireShared(current);
+        }
+
+        /**
+         * Full version of acquire for reads, that handles CAS misses
+         * and reentrant reads not dealt with in tryAcquireShared.
          */
-        final int nonfairTryAcquireShared(int acquires) {
+        final int fullTryAcquireShared(Thread current) {
+            /*
+             * This code is in part redundant with that in
+             * tryAcquireShared but is simpler overall by not
+             * complicating tryAcquireShared with interactions between
+             * retries and lazily reading hold counts.
+             */
+            HoldCounter rh = null;
             for (;;) {
                 int c = getState();
-                int nextc = c + (acquires << SHARED_SHIFT);
-                if (nextc < c)
+                if (exclusiveCount(c) != 0) {
+                    if (getExclusiveOwnerThread() != current)
+                        return -1;
+                    // else we hold the exclusive lock; blocking here
+                    // would cause deadlock.
+                } else if (readerShouldBlock()) {
+                    // Make sure we're not acquiring read lock reentrantly
+                    if (firstReader == current) {
+                        // assert firstReaderHoldCount > 0;
+                    } else {
+                        if (rh == null) {
+                            rh = cachedHoldCounter;
+                            if (rh == null || rh.tid != current.getId()) {
+                                rh = readHolds.get();
+                                if (rh.count == 0)
+                                    readHolds.remove();
+                            }
+                        }
+                        if (rh.count == 0)
+                            return -1;
+                    }
+                }
+                if (sharedCount(c) == MAX_COUNT)
                     throw new Error("Maximum lock count exceeded");
-                if (exclusiveCount(c) != 0 && 
-                    owner != Thread.currentThread())
-                    return -1;
-                if (compareAndSetState(c, nextc)) 
+                if (compareAndSetState(c, c + SHARED_UNIT)) {
+                    if (sharedCount(c) == 0) {
+                        firstReader = current;
+                        firstReaderHoldCount = 1;
+                    } else if (firstReader == current) {
+                        firstReaderHoldCount++;
+                    } else {
+                        if (rh == null)
+                            rh = cachedHoldCounter;
+                        if (rh == null || rh.tid != current.getId())
+                            rh = readHolds.get();
+                        else if (rh.count == 0)
+                            readHolds.set(rh);
+                        rh.count++;
+                        cachedHoldCounter = rh; // cache for release
+                    }
                     return 1;
-                // Recheck count if lost CAS
+                }
             }
         }
 
-        protected final boolean tryRelease(int releases) {
+        /**
+         * Performs tryLock for write, enabling barging in both modes.
+         * This is identical in effect to tryAcquire except for lack
+         * of calls to writerShouldBlock.
+         */
+        final boolean tryWriteLock() {
             Thread current = Thread.currentThread();
             int c = getState();
-            if (owner != current)
-                throw new IllegalMonitorStateException();
-            int nextc = c - releases;
-            boolean free = false;
-            if (exclusiveCount(c) == releases) {
-                free = true;
-                owner = null;
+            if (c != 0) {
+                int w = exclusiveCount(c);
+                if (w == 0 || current != getExclusiveOwnerThread())
+                    return false;
+                if (w == MAX_COUNT)
+                    throw new Error("Maximum lock count exceeded");
             }
-            setState(nextc);
-            return free;
+            if (!compareAndSetState(c, c + 1))
+                return false;
+            setExclusiveOwnerThread(current);
+            return true;
         }
 
-        protected final boolean tryReleaseShared(int releases) {
+        /**
+         * Performs tryLock for read, enabling barging in both modes.
+         * This is identical in effect to tryAcquireShared except for
+         * lack of calls to readerShouldBlock.
+         */
+        final boolean tryReadLock() {
+            Thread current = Thread.currentThread();
             for (;;) {
                 int c = getState();
-                int nextc = c - (releases << SHARED_SHIFT);
-                if (nextc < 0)
-                    throw new IllegalMonitorStateException();
-                if (compareAndSetState(c, nextc)) 
-                    return nextc == 0;
+                if (exclusiveCount(c) != 0 &&
+                    getExclusiveOwnerThread() != current)
+                    return false;
+                int r = sharedCount(c);
+                if (r == MAX_COUNT)
+                    throw new Error("Maximum lock count exceeded");
+                if (compareAndSetState(c, c + SHARED_UNIT)) {
+                    if (r == 0) {
+                        firstReader = current;
+                        firstReaderHoldCount = 1;
+                    } else if (firstReader == current) {
+                        firstReaderHoldCount++;
+                    } else {
+                        HoldCounter rh = cachedHoldCounter;
+                        if (rh == null || rh.tid != current.getId())
+                            cachedHoldCounter = rh = readHolds.get();
+                        else if (rh.count == 0)
+                            readHolds.set(rh);
+                        rh.count++;
+                    }
+                    return true;
+                }
             }
         }
-    
+
         protected final boolean isHeldExclusively() {
-            return exclusiveCount(getState()) != 0 && 
-                owner == Thread.currentThread();
+            // While we must in general read state before owner,
+            // we don't need to do so to check if current thread is owner
+            return getExclusiveOwnerThread() == Thread.currentThread();
         }
 
         // Methods relayed to outer class
-        
-        final ConditionObject newCondition() { 
-            return new ConditionObject(); 
+
+        final ConditionObject newCondition() {
+            return new ConditionObject();
         }
 
         final Thread getOwner() {
-            int c = exclusiveCount(getState());
-            Thread o = owner;
-            return (c == 0)? null : o;
+            // Must read state before owner to ensure memory consistency
+            return ((exclusiveCount(getState()) == 0)?
+                    null :
+                    getExclusiveOwnerThread());
         }
-        
+
         final int getReadLockCount() {
             return sharedCount(getState());
         }
-        
+
         final boolean isWriteLocked() {
             return exclusiveCount(getState()) != 0;
         }
 
         final int getWriteHoldCount() {
-            int c = exclusiveCount(getState());
-            Thread o = owner;
-            return (o == Thread.currentThread())? c : 0;
+            return isHeldExclusively() ? exclusiveCount(getState()) : 0;
+        }
+
+        final int getReadHoldCount() {
+            if (getReadLockCount() == 0)
+                return 0;
+
+            Thread current = Thread.currentThread();
+            if (firstReader == current)
+                return firstReaderHoldCount;
+
+            HoldCounter rh = cachedHoldCounter;
+            if (rh != null && rh.tid == current.getId())
+                return rh.count;
+
+            int count = readHolds.get().count;
+            if (count == 0) readHolds.remove();
+            return count;
         }
 
         /**
@@ -315,78 +630,43 @@
         private void readObject(java.io.ObjectInputStream s)
             throws java.io.IOException, ClassNotFoundException {
             s.defaultReadObject();
+            readHolds = new ThreadLocalHoldCounter();
             setState(0); // reset to unlocked state
         }
 
         final int getCount() { return getState(); }
     }
 
-    /** 
+    /**
      * Nonfair version of Sync
      */
     final static class NonfairSync extends Sync {
-        protected final boolean tryAcquire(int acquires) { 
-            return nonfairTryAcquire(acquires);
-        }
-
-        protected final int tryAcquireShared(int acquires) {
-            return nonfairTryAcquireShared(acquires);
-        }
-
-        // Use fastpath for main write lock method
-        final void wlock() {
-            if (compareAndSetState(0, 1))
-                owner = Thread.currentThread();
-            else
-                acquire(1);
+        private static final long serialVersionUID = -8159625535654395037L;
+        final boolean writerShouldBlock() {
+            return false; // writers can always barge
+        }
+        final boolean readerShouldBlock() {
+            /* As a heuristic to avoid indefinite writer starvation,
+             * block if the thread that momentarily appears to be head
+             * of queue, if one exists, is a waiting writer.  This is
+             * only a probabilistic effect since a new reader will not
+             * block if there is a waiting writer behind other enabled
+             * readers that have not yet drained from the queue.
+             */
+            return apparentlyFirstQueuedIsExclusive();
         }
     }
 
-    /** 
+    /**
      * Fair version of Sync
      */
     final static class FairSync extends Sync {
-        protected final boolean tryAcquire(int acquires) { 
-            // mask out readlocks if called from condition methods
-            acquires = exclusiveCount(acquires);
-            Thread current = Thread.currentThread();
-            Thread first;
-            int c = getState();
-            int w = exclusiveCount(c);
-            if (w + acquires >= SHARED_UNIT)
-                throw new Error("Maximum lock count exceeded");
-            if ((w == 0 || current != owner) &&
-                (c != 0 || 
-                 ((first = getFirstQueuedThread()) != null && 
-                  first != current)))
-                return false;
-            if (!compareAndSetState(c, c + acquires)) 
-                return false;
-            owner = current;
-            return true;
-        }
-
-        protected final int tryAcquireShared(int acquires) {
-            Thread current = Thread.currentThread();
-            for (;;) {
-                Thread first = getFirstQueuedThread();
-                if (first != null && first != current)
-                    return -1;
-                int c = getState();
-                int nextc = c + (acquires << SHARED_SHIFT);
-                if (nextc < c)
-                    throw new Error("Maximum lock count exceeded");
-                if (exclusiveCount(c) != 0 && 
-                    owner != Thread.currentThread())
-                    return -1;
-                if (compareAndSetState(c, nextc)) 
-                    return 1;
-                // Recheck count if lost CAS
-            }
+        private static final long serialVersionUID = -2274990926593161451L;
+        final boolean writerShouldBlock() {
+            return hasQueuedPredecessors();
         }
-
-        final void wlock() { // no fast path
-            acquire(1);
+        final boolean readerShouldBlock() {
+            return hasQueuedPredecessors();
         }
     }
 
@@ -396,46 +676,47 @@
     public static class ReadLock implements Lock, java.io.Serializable  {
         private static final long serialVersionUID = -5992448646407690164L;
         private final Sync sync;
-        
-        /** 
-         * Constructor for use by subclasses.
+
+        /**
+         * Constructor for use by subclasses
+         *
          * @param lock the outer lock object
-         * @throws NullPointerException if lock null
+         * @throws NullPointerException if the lock is null
          */
         protected ReadLock(ReentrantReadWriteLock lock) {
             sync = lock.sync;
         }
 
         /**
-         * Acquires the shared lock. 
+         * Acquires the read lock.
          *
-         * <p>Acquires the lock if it is not held exclusively by
+         * <p>Acquires the read lock if the write lock is not held by
          * another thread and returns immediately.
          *
-         * <p>If the lock is held exclusively by another thread then
+         * <p>If the write lock is held by another thread then
          * the current thread becomes disabled for thread scheduling
-         * purposes and lies dormant until the lock has been acquired.
+         * purposes and lies dormant until the read lock has been acquired.
          */
-        public void lock() { 
+        public void lock() {
             sync.acquireShared(1);
         }
 
         /**
-         * Acquires the shared lock unless the current thread is 
-         * {@link Thread#interrupt interrupted}.
+         * Acquires the read lock unless the current thread is
+         * {@linkplain Thread#interrupt interrupted}.
          *
-         * <p>Acquires the shared lock if it is not held exclusively
+         * <p>Acquires the read lock if the write lock is not held
          * by another thread and returns immediately.
          *
-         * <p>If the lock is held by another thread then the
-         * current thread becomes disabled for thread scheduling 
+         * <p>If the write lock is held by another thread then the
+         * current thread becomes disabled for thread scheduling
          * purposes and lies dormant until one of two things happens:
          *
          * <ul>
          *
-         * <li>The lock is acquired by the current thread; or
+         * <li>The read lock is acquired by the current thread; or
          *
-         * <li>Some other thread {@link Thread#interrupt interrupts}
+         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
          * the current thread.
          *
          * </ul>
@@ -444,10 +725,10 @@
          *
          * <ul>
          *
-         * <li>has its interrupted status set on entry to this method; or 
+         * <li>has its interrupted status set on entry to this method; or
          *
-         * <li>is {@link Thread#interrupt interrupted} while acquiring 
-         * the lock,
+         * <li>is {@linkplain Thread#interrupt interrupted} while
+         * acquiring the read lock,
          *
          * </ul>
          *
@@ -466,83 +747,83 @@
         }
 
         /**
-         * Acquires the shared lock only if it is not held exclusively by
+         * Acquires the read lock only if the write lock is not held by
          * another thread at the time of invocation.
          *
-         * <p>Acquires the lock if it is not held exclusively by
+         * <p>Acquires the read lock if the write lock is not held by
          * another thread and returns immediately with the value
-         * <tt>true</tt>. 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
+         * {@code true}. Even when this lock has been set to use a
+         * fair ordering policy, a call to {@code tryLock()}
+         * <em>will</em> immediately acquire the read lock if it is
          * available, whether or not other threads are currently
-         * waiting for the lock.  This &quot;barging&quot; behavior
+         * waiting for the read lock.  This &quot;barging&quot; behavior
          * can be useful in certain circumstances, even though it
          * breaks fairness. If you want to honor the fairness setting
          * for this lock, then use {@link #tryLock(long, TimeUnit)
          * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
          * (it also detects interruption).
          *
-         * <p>If the lock is held exclusively by another thread then
+         * <p>If the write lock is held by another thread then
          * this method will return immediately with the value
-         * <tt>false</tt>.
+         * {@code false}.
          *
-         * @return <tt>true</tt> if the lock was acquired.
+         * @return {@code true} if the read lock was acquired
          */
         public  boolean tryLock() {
-            return sync.nonfairTryAcquireShared(1) >= 0;
+            return sync.tryReadLock();
         }
 
         /**
-         * Acquires the shared lock if it is not held exclusively by
+         * Acquires the read lock if the write lock is not held by
          * another thread within the given waiting time and the
-         * current thread has not been {@link Thread#interrupt
+         * current thread has not been {@linkplain Thread#interrupt
          * interrupted}.
          *
-         * <p>Acquires the lock if it is not held exclusively by
+         * <p>Acquires the read lock if the write lock is not held by
          * another thread and returns immediately with the value
-         * <tt>true</tt>. If this lock has been set to use a fair
+         * {@code true}. If this lock has been set to use a fair
          * ordering policy then an available lock <em>will not</em> be
          * acquired if any other threads are waiting for the
          * lock. This is in contrast to the {@link #tryLock()}
-         * method. If you want a timed <tt>tryLock</tt> that does
+         * method. If you want a timed {@code tryLock} that does
          * permit barging on a fair lock then combine the timed and
          * un-timed forms together:
          *
          * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
          * </pre>
          *
-         * <p>If the lock is held exclusively by another thread then the
-         * current thread becomes disabled for thread scheduling 
+         * <p>If the write lock is held by another thread then the
+         * current thread becomes disabled for thread scheduling
          * purposes and lies dormant until one of three things happens:
          *
          * <ul>
          *
-         * <li>The lock is acquired by the current thread; or
+         * <li>The read lock is acquired by the current thread; or
          *
-         * <li>Some other thread {@link Thread#interrupt interrupts} the current
-         * thread; or
+         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
+         * the current thread; or
          *
-         * <li>The specified waiting time elapses
+         * <li>The specified waiting time elapses.
          *
          * </ul>
          *
-         * <p>If the lock is acquired then the value <tt>true</tt> is
+         * <p>If the read lock is acquired then the value {@code true} is
          * returned.
          *
          * <p>If the current thread:
          *
          * <ul>
          *
-         * <li>has its interrupted status set on entry to this method; or 
+         * <li>has its interrupted status set on entry to this method; or
          *
-         * <li>is {@link Thread#interrupt interrupted} while acquiring
-         * the lock,
+         * <li>is {@linkplain Thread#interrupt interrupted} while
+         * acquiring the read lock,
          *
          * </ul> then {@link InterruptedException} is thrown and the
          * current thread's interrupted status is cleared.
          *
          * <p>If the specified waiting time elapses then the value
-         * <tt>false</tt> is returned.  If the time is less than or
+         * {@code false} is returned.  If the time is less than or
          * equal to zero, the method will not wait at all.
          *
          * <p>In this implementation, as this method is an explicit
@@ -550,13 +831,11 @@
          * 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 timeout the time to wait for the read lock
          * @param unit the time unit of the timeout argument
-         *
-         * @return <tt>true</tt> if the lock was acquired.
-         *
+         * @return {@code true} if the read lock was acquired
          * @throws InterruptedException if the current thread is interrupted
-         * @throws NullPointerException if unit is null
+         * @throws NullPointerException if the time unit is null
          *
          */
         public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
@@ -564,20 +843,19 @@
         }
 
         /**
-         * Attempts to release this lock.  
+         * Attempts to release this lock.
          *
          * <p> If the number of readers is now zero then the lock
-         * is made available for other lock attempts.
+         * is made available for write lock attempts.
          */
         public  void unlock() {
             sync.releaseShared(1);
         }
 
         /**
-         * Throws UnsupportedOperationException because ReadLocks
-         * do not support conditions.
-         * @return A new {@link Condition} instance for this <tt>Lock</tt>
-         * instance.
+         * Throws {@code UnsupportedOperationException} because
+         * {@code ReadLocks} do not support conditions.
+         *
          * @throws UnsupportedOperationException always
          */
         public Condition newCondition() {
@@ -586,17 +864,16 @@
 
         /**
          * Returns a string identifying this lock, as well as its lock state.
-         * The state, in brackets, includes the String 
-         * &quot;Read locks =&quot; followed by the number of held
-         * read locks.
-         * @return a string identifying this lock, as well as its lock state.
+         * The state, in brackets, includes the String {@code "Read locks ="}
+         * followed by the number of held read locks.
+         *
+         * @return a string identifying this lock, as well as its lock state
          */
         public String toString() {
             int r = sync.getReadLockCount();
-            return super.toString() + 
+            return super.toString() +
                 "[Read locks = " + r + "]";
         }
-
     }
 
     /**
@@ -605,42 +882,45 @@
     public static class WriteLock implements Lock, java.io.Serializable  {
         private static final long serialVersionUID = -4992448646407690164L;
         private final Sync sync;
-        
-        /** 
-         * Constructor for use by subclasses.
+
+        /**
+         * Constructor for use by subclasses
+         *
          * @param lock the outer lock object
-         * @throws NullPointerException if lock null
+         * @throws NullPointerException if the lock is null
          */
         protected WriteLock(ReentrantReadWriteLock lock) {
             sync = lock.sync;
         }
 
         /**
-         * Acquire the lock. 
+         * Acquires the write lock.
          *
-         * <p>Acquires the lock if it is not held by another thread
-         * and returns immediately, setting the lock hold count to
+         * <p>Acquires the write lock if neither the read nor write lock
+         * are held by another thread
+         * and returns immediately, setting the write lock hold count to
          * one.
          *
-         * <p>If the current thread already holds the lock then the
+         * <p>If the current thread already holds the write lock then the
          * hold count is incremented by one and the method returns
          * immediately.
          *
          * <p>If the lock is held by another thread then the current
          * thread becomes disabled for thread scheduling purposes and
-         * lies dormant until the lock has been acquired, at which
-         * time the lock hold count is set to one.
+         * lies dormant until the write lock has been acquired, at which
+         * time the write lock hold count is set to one.
          */
         public void lock() {
-            sync.wlock();
+            sync.acquire(1);
         }
 
         /**
-         * Acquires the lock unless the current thread is {@link
-         * Thread#interrupt interrupted}.
+         * Acquires the write lock unless the current thread is
+         * {@linkplain Thread#interrupt interrupted}.
          *
-         * <p>Acquires the lock if it is not held by another thread
-         * and returns immediately, setting the lock hold count to
+         * <p>Acquires the write lock if neither the read nor write lock
+         * are held by another thread
+         * and returns immediately, setting the write lock hold count to
          * one.
          *
          * <p>If the current thread already holds this lock then the
@@ -653,14 +933,14 @@
          *
          * <ul>
          *
-         * <li>The lock is acquired by the current thread; or
+         * <li>The write lock is acquired by the current thread; or
          *
-         * <li>Some other thread {@link Thread#interrupt interrupts}
+         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
          * the current thread.
          *
          * </ul>
          *
-         * <p>If the lock is acquired by the current thread then the
+         * <p>If the write lock is acquired by the current thread then the
          * lock hold count is set to one.
          *
          * <p>If the current thread:
@@ -670,8 +950,8 @@
          * <li>has its interrupted status set on entry to this method;
          * or
          *
-         * <li>is {@link Thread#interrupt interrupted} while acquiring
-         * the lock,
+         * <li>is {@linkplain Thread#interrupt interrupted} while
+         * acquiring the write lock,
          *
          * </ul>
          *
@@ -690,16 +970,17 @@
         }
 
         /**
-         * Acquires the lock only if it is not held by another thread
+         * Acquires the write 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
+         * <p>Acquires the write lock if neither the read nor write lock
+         * are held by another thread
+         * and returns immediately with the value {@code true},
+         * setting the write lock hold count to one. Even when this lock has
          * been set to use a fair ordering policy, a call to
-         * <tt>tryLock()</tt> <em>will</em> immediately acquire the
+         * {@code tryLock()} <em>will</em> immediately acquire the
          * lock if it is available, whether or not other threads are
-         * currently waiting for the lock.  This &quot;barging&quot;
+         * currently waiting for the write lock.  This &quot;barging&quot;
          * behavior can be useful in certain circumstances, even
          * though it breaks fairness. If you want to honor the
          * fairness setting for this lock, then use {@link
@@ -708,31 +989,32 @@
          *
          * <p> If the current thread already holds this lock then the
          * hold count is incremented by one and the method returns
-         * <tt>true</tt>.
+         * {@code true}.
          *
          * <p>If the lock is held by another thread then this method
-         * will return immediately with the value <tt>false</tt>.
+         * will return immediately with the value {@code false}.
          *
-         * @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.
+         * @return {@code true} if the lock was free and was acquired
+         * by the current thread, or the write lock was already held
+         * by the current thread; and {@code false} otherwise.
          */
         public boolean tryLock( ) {
-            return sync.nonfairTryAcquire(1);
+            return sync.tryWriteLock();
         }
 
         /**
-         * Acquires the lock if it is not held by another thread
+         * Acquires the write 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}.
+         * not been {@linkplain 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
+         * <p>Acquires the write lock if neither the read nor write lock
+         * are held by another thread
+         * and returns immediately with the value {@code true},
+         * setting the write lock hold count to one. If this lock has been
          * set to use a fair ordering policy then an available lock
          * <em>will not</em> be acquired if any other threads are
-         * waiting for the lock. This is in contrast to the {@link
-         * #tryLock()} method. If you want a timed <tt>tryLock</tt>
+         * waiting for the write lock. This is in contrast to the {@link
+         * #tryLock()} method. If you want a timed {@code tryLock}
          * that does permit barging on a fair lock then combine the
          * timed and un-timed forms together:
          *
@@ -741,7 +1023,7 @@
          *
          * <p>If the current thread already holds this lock then the
          * hold count is incremented by one and the method returns
-         * <tt>true</tt>.
+         * {@code true}.
          *
          * <p>If the lock is held by another thread then the current
          * thread becomes disabled for thread scheduling purposes and
@@ -749,17 +1031,17 @@
          *
          * <ul>
          *
-         * <li>The lock is acquired by the current thread; or
+         * <li>The write lock is acquired by the current thread; or
          *
-         * <li>Some other thread {@link Thread#interrupt interrupts}
+         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
          * the current thread; or
          *
          * <li>The specified waiting time elapses
          *
          * </ul>
          *
-         * <p>If the lock is acquired then the value <tt>true</tt> is
-         * returned and the lock hold count is set to one.
+         * <p>If the write lock is acquired then the value {@code true} is
+         * returned and the write lock hold count is set to one.
          *
          * <p>If the current thread:
          *
@@ -768,16 +1050,16 @@
          * <li>has its interrupted status set on entry to this method;
          * or
          *
-         * <li>is {@link Thread#interrupt interrupted} while acquiring
-         * the lock,
+         * <li>is {@linkplain Thread#interrupt interrupted} while
+         * acquiring the write lock,
          *
-         * </ul> 
+         * </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
+         * {@code false} is returned.  If the time is less than or
          * equal to zero, the method will not wait at all.
          *
          * <p>In this implementation, as this method is an explicit
@@ -785,30 +1067,31 @@
          * 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 timeout the time to wait for the write 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
+         * @return {@code true} if the lock was free and was acquired
+         * by the current thread, or the write lock was already held by the
+         * current thread; and {@code false} if the waiting time
          * elapsed before the lock could be acquired.
          *
          * @throws InterruptedException if the current thread is interrupted
-         * @throws NullPointerException if unit is null
+         * @throws NullPointerException if the time unit is null
          *
          */
         public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
             return sync.tryAcquireNanos(1, unit.toNanos(timeout));
         }
-        
+
         /**
-         * Attempts to release this lock.  
+         * 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.
          */
@@ -818,7 +1101,7 @@
 
         /**
          * Returns a {@link Condition} instance for use with this
-         * {@link Lock} instance. 
+         * {@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
@@ -834,74 +1117,80 @@
          * affected. However it is essentially always an error to
          * invoke a condition waiting method when the current thread
          * has also acquired read locks, since other threads that
-         * could unblock it will not be able to access the write
+         * could unblock it will not be able to acquire the write
          * lock.)
          *
-         * <li>When the condition {@link Condition#await() waiting}
+         * <li>When the condition {@linkplain Condition#await() waiting}
          * methods are called the write lock is released and, before
          * they return, the write lock is reacquired and the lock hold
          * count restored to what it was when the method was called.
          *
-         * <li>If a thread is {@link Thread#interrupt interrupted} while
+         * <li>If a thread is {@linkplain Thread#interrupt interrupted} while
          * waiting then the wait will terminate, an {@link
          * InterruptedException} will be thrown, and the thread's
          * interrupted status will be cleared.
          *
-         * <li> Waiting threads are signalled in FIFO order
+         * <li> 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() { 
+        public Condition newCondition() {
             return sync.newCondition();
         }
 
         /**
          * Returns a string identifying this lock, as well as its lock
          * state.  The state, in brackets includes either the String
-         * &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.
+         * {@code "Unlocked"} or the String {@code "Locked by"}
+         * followed by the {@linkplain Thread#getName name} of the owning thread.
+         *
+         * @return a string identifying this lock, as well as its lock state
          */
         public String toString() {
-            Thread owner = sync.getOwner();
-            return super.toString() + ((owner == null) ?
+            Thread o = sync.getOwner();
+            return super.toString() + ((o == null) ?
                                        "[Unlocked]" :
-                                       "[Locked by thread " + owner.getName() + "]");
+                                       "[Locked by thread " + o.getName() + "]");
         }
 
     }
 
-
     // Instrumentation and status
 
     /**
-     * Returns true if this lock has fairness set true.
-     * @return true if this lock has fairness set true.
+     * Returns {@code true} if this lock has fairness set true.
+     *
+     * @return {@code true} if this lock has fairness set true
      */
     public final boolean isFair() {
         return sync instanceof FairSync;
     }
 
     /**
-     * Returns the thread that currently owns the 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.
+     * Returns the thread that currently owns the write lock, or
+     * {@code null} if not owned. When this method is called by a
+     * thread that is not the owner, the return value reflects a
+     * best-effort approximation of current lock status. For example,
+     * the owner may be momentarily {@code null} even if there are
+     * threads trying to acquire the lock but have not yet done so.
+     * This method is designed to facilitate construction of
+     * subclasses that provide more extensive lock monitoring
+     * facilities.
+     *
+     * @return the owner, or {@code null} if not owned
      */
     protected Thread getOwner() {
         return sync.getOwner();
     }
-    
+
     /**
      * Queries the number of read locks held for this lock. This
      * method is designed for use in monitoring system state, not for
@@ -916,17 +1205,19 @@
      * Queries if the write lock is held by any thread. This method is
      * designed for use in monitoring system state, not for
      * synchronization control.
-     * @return <tt>true</tt> if any thread holds write lock and 
-     * <tt>false</tt> otherwise.
+     *
+     * @return {@code true} if any thread holds the write lock and
+     *         {@code false} otherwise
      */
     public boolean isWriteLocked() {
         return sync.isWriteLocked();
     }
 
     /**
-     * Queries if the write lock is held by the current thread. 
-     * @return <tt>true</tt> if current thread holds this lock and 
-     * <tt>false</tt> otherwise.
+     * Queries if the write lock is held by the current thread.
+     *
+     * @return {@code true} if the current thread holds the write lock and
+     *         {@code false} otherwise
      */
     public boolean isWriteLockedByCurrentThread() {
         return sync.isHeldExclusively();
@@ -937,8 +1228,8 @@
      * current thread.  A writer thread has a hold on a lock for
      * each lock action that is not matched by an unlock action.
      *
-     * @return the number of holds on this lock by the current thread,
-     * or zero if this lock is not held by the current thread.
+     * @return the number of holds on the write lock by the current thread,
+     *         or zero if the write lock is not held by the current thread
      */
     public int getWriteHoldCount() {
         return sync.getWriteHoldCount();
@@ -952,6 +1243,7 @@
      * returned collection are in no particular order.  This method is
      * designed to facilitate construction of subclasses that provide
      * more extensive lock monitoring facilities.
+     *
      * @return the collection of threads
      */
     protected Collection<Thread> getQueuedWriterThreads() {
@@ -966,6 +1258,7 @@
      * returned collection are in no particular order.  This method is
      * designed to facilitate construction of subclasses that provide
      * more extensive lock monitoring facilities.
+     *
      * @return the collection of threads
      */
     protected Collection<Thread> getQueuedReaderThreads() {
@@ -973,41 +1266,42 @@
     }
 
     /**
-     * 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.
+     * Queries whether any threads are waiting to acquire the read or
+     * write lock. Note that because cancellations may occur at any
+     * time, a {@code true} return does not guarantee that any other
+     * thread will ever acquire a lock.  This method is designed
+     * primarily for use in monitoring of the system state.
      *
-     * @return true if there may be other threads waiting to acquire
-     * the lock.
+     * @return {@code true} if there may be other threads waiting to
+     *         acquire the lock
      */
-    public final boolean hasQueuedThreads() { 
+    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.
+     * Queries whether the given thread is waiting to acquire either
+     * the read or write lock. Note that because cancellations may
+     * occur at any time, a {@code true} return does not guarantee
+     * that this thread will ever acquire a lock.  This method is
+     * designed primarily for use in monitoring of the system state.
      *
      * @param thread the thread
-     * @return true if the given thread is queued waiting for this lock.
-     * @throws NullPointerException if thread is null
+     * @return {@code true} if the given thread is queued waiting for this lock
+     * @throws NullPointerException if the thread is null
      */
-    public final boolean hasQueuedThread(Thread thread) { 
+    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.
+     * Returns an estimate of the number of threads waiting to acquire
+     * either the read or write lock.  The value is only an estimate
+     * because the number of threads may change dynamically while this
+     * method traverses internal data structures.  This method is
+     * designed for use in monitoring of the system state, not for
+     * synchronization control.
+     *
      * @return the estimated number of threads waiting for this lock
      */
     public final int getQueueLength() {
@@ -1016,12 +1310,13 @@
 
     /**
      * 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.
+     * acquire either the read or write lock.  Because the actual set
+     * of threads may change dynamically while constructing this
+     * result, the returned collection is only a best-effort estimate.
+     * The elements of the returned collection are in no particular
+     * order.  This method is designed to facilitate construction of
+     * subclasses that provide more extensive monitoring facilities.
+     *
      * @return the collection of threads
      */
     protected Collection<Thread> getQueuedThreads() {
@@ -1031,18 +1326,18 @@
     /**
      * Queries whether any threads are waiting on the given condition
      * associated with the write lock. Note that because timeouts and
-     * interrupts may occur at any time, a <tt>true</tt> return does
-     * not guarantee that a future <tt>signal</tt> will awaken any
+     * interrupts may occur at any time, a {@code true} return does
+     * not guarantee that a future {@code signal} will awaken any
      * threads.  This method is designed primarily for use in
      * monitoring of the system state.
+     *
      * @param condition the condition
-     * @return <tt>true</tt> if there are any waiting threads.
-     * @throws IllegalMonitorStateException if this lock 
-     * is not held
+     * @return {@code true} if there are any waiting threads
+     * @throws IllegalMonitorStateException if this lock is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this lock
-     * @throws NullPointerException if condition null
-     */ 
+     *         not associated with this lock
+     * @throws NullPointerException if the condition is null
+     */
     public boolean hasWaiters(Condition condition) {
         if (condition == null)
             throw new NullPointerException();
@@ -1058,14 +1353,14 @@
      * 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
+     * @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
-     */ 
+     *         not associated with this lock
+     * @throws NullPointerException if the condition is null
+     */
     public int getWaitQueueLength(Condition condition) {
         if (condition == null)
             throw new NullPointerException();
@@ -1083,13 +1378,13 @@
      * 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 IllegalMonitorStateException if this lock is not held
      * @throws IllegalArgumentException if the given condition is
-     * not associated with this lock
-     * @throws NullPointerException if condition null
+     *         not associated with this lock
+     * @throws NullPointerException if the condition is null
      */
     protected Collection<Thread> getWaitingThreads(Condition condition) {
         if (condition == null)
@@ -1101,18 +1396,19 @@
 
     /**
      * Returns a string identifying this lock, as well as its lock state.
-     * The state, in brackets, includes the String &quot;Write locks =&quot;
-     * follwed by the number of reentrantly held write locks, and the
-     * String &quot;Read locks =&quot; followed by the number of held
+     * The state, in brackets, includes the String {@code "Write locks ="}
+     * followed by the number of reentrantly held write locks, and the
+     * String {@code "Read locks ="} followed by the number of held
      * read locks.
-     * @return a string identifying this lock, as well as its lock state.
+     *
+     * @return a string identifying this lock, as well as its lock state
      */
     public String toString() {
         int c = sync.getCount();
-        int w = exclusiveCount(c);
-        int r = sharedCount(c);
-        
-        return super.toString() + 
+        int w = Sync.exclusiveCount(c);
+        int r = Sync.sharedCount(c);
+
+        return super.toString() +
             "[Write locks = " + w + ", Read locks = " + r + "]";
     }
 

Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AbstractQueuedSynchronizerTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AbstractQueuedSynchronizerTest.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AbstractQueuedSynchronizerTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AbstractQueuedSynchronizerTest.java Tue Jul 28 09:30:33 2009
@@ -461,7 +461,9 @@
 	Thread t = new Thread(new InterruptedSyncRunnable(sync));
         try {
             t.start();
+            Thread.sleep(SHORT_DELAY_MS);
             t.interrupt();
+            Thread.sleep(SHORT_DELAY_MS);
             sync.release(1);
             t.join();
         } catch(Exception e){
@@ -950,7 +952,6 @@
             sync.acquire(1);
             c.signal();
             sync.release(1);
-            assert(t.isInterrupted());
             t.join(SHORT_DELAY_MS);
             assertFalse(t.isAlive());
         }

Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/ArrayBlockingQueueTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/ArrayBlockingQueueTest.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/ArrayBlockingQueueTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/ArrayBlockingQueueTest.java Tue Jul 28 09:30:33 2009
@@ -650,6 +650,7 @@
         assertEquals(SIZE, q.remainingCapacity());
         q.add(one);
         assertFalse(q.isEmpty());
+        assertTrue(q.contains(one));
         q.clear();
         assertTrue(q.isEmpty());
     }
@@ -970,6 +971,17 @@
         assertEquals(l.size(), SIZE);
         for (int i = 0; i < SIZE; ++i) 
             assertEquals(l.get(i), new Integer(i));
+        q.add(zero);
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(zero));
+        assertTrue(q.contains(one));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(q.size(), 0);
+        assertEquals(l.size(), 2);
+        for (int i = 0; i < 2; ++i) 
+            assertEquals(l.get(i), new Integer(i));
     }
 
     /**
@@ -1028,15 +1040,18 @@
      * drainTo(c, n) empties first max {n, size} elements of queue into c
      */ 
     public void testDrainToN() {
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE*2);
         for (int i = 0; i < SIZE + 2; ++i) {
-            ArrayBlockingQueue q = populatedQueue(SIZE);
+            for(int j = 0; j < SIZE; j++)
+                assertTrue(q.offer(new Integer(j)));
             ArrayList l = new ArrayList();
             q.drainTo(l, i);
             int k = (i < SIZE)? i : SIZE;
-            assertEquals(q.size(), SIZE-k);
             assertEquals(l.size(), k);
+            assertEquals(q.size(), SIZE-k);
             for (int j = 0; j < k; ++j) 
                 assertEquals(l.get(j), new Integer(j));
+            while (q.poll() != null) ;
         }
     }
 

Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicIntegerFieldUpdaterTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicIntegerFieldUpdaterTest.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicIntegerFieldUpdaterTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicIntegerFieldUpdaterTest.java Tue Jul 28 09:30:33 2009
@@ -60,6 +60,27 @@
         catch (RuntimeException rt) {}
     }
 
+    static class Base {
+        protected volatile int f = 0;
+    }
+    static class Sub1 extends Base {
+        AtomicIntegerFieldUpdater<Base> fUpdater
+                = AtomicIntegerFieldUpdater.newUpdater(Base.class, "f");
+    }
+    static class Sub2 extends Base {}
+
+    public void testProtectedFieldOnAnotherSubtype() {
+        Sub1 sub1 = new Sub1();
+        Sub2 sub2 = new Sub2();
+
+        sub1.fUpdater.set(sub1, 1);
+        try {
+            sub1.fUpdater.set(sub2, 2);
+            shouldThrow();
+        } 
+        catch (RuntimeException rt) {}
+    }
+
     /**
      *  get returns the last value set or assigned
      */
@@ -78,6 +99,7 @@
 	assertEquals(-3,a.get(this));
 	
     }
+
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */

Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicIntegerTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicIntegerTest.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicIntegerTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicIntegerTest.java Tue Jul 28 09:30:33 2009
@@ -46,6 +46,7 @@
 	assertEquals(-3,ai.get());
 	
     }
+
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */

Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicLongFieldUpdaterTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicLongFieldUpdaterTest.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicLongFieldUpdaterTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicLongFieldUpdaterTest.java Tue Jul 28 09:30:33 2009
@@ -62,6 +62,27 @@
         catch (RuntimeException rt) {}
     }
 
+    static class Base {
+        protected volatile long f = 0;
+    }
+    static class Sub1 extends Base {
+        AtomicLongFieldUpdater<Base> fUpdater
+                = AtomicLongFieldUpdater.newUpdater(Base.class, "f");
+    }
+    static class Sub2 extends Base {}
+
+    public void testProtectedFieldOnAnotherSubtype() {
+        Sub1 sub1 = new Sub1();
+        Sub2 sub2 = new Sub2();
+
+        sub1.fUpdater.set(sub1, 1);
+        try {
+            sub1.fUpdater.set(sub2, 2);
+            shouldThrow();
+        }
+        catch (RuntimeException rt) {}
+    }
+
     /**
      *  get returns the last value set or assigned
      */
@@ -78,7 +99,7 @@
 	assertEquals(2,a.get(this));
 	a.set(this,-3);
 	assertEquals(-3,a.get(this));
-	
+
     }
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails

Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicLongTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicLongTest.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicLongTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicLongTest.java Tue Jul 28 09:30:33 2009
@@ -46,6 +46,7 @@
 	assertEquals(-3,ai.get());
 	
     }
+
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails
      */

Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicReferenceFieldUpdaterTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicReferenceFieldUpdaterTest.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicReferenceFieldUpdaterTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicReferenceFieldUpdaterTest.java Tue Jul 28 09:30:33 2009
@@ -62,6 +62,27 @@
         catch (RuntimeException rt) {}
     }
 
+    static class Base {
+        protected volatile Object f = null;
+    }
+    static class Sub1 extends Base {
+        AtomicReferenceFieldUpdater<Base, Object> fUpdater
+                = AtomicReferenceFieldUpdater.newUpdater(Base.class, Object.class, "f");
+    }
+    static class Sub2 extends Base {}
+
+    public void testProtectedFieldOnAnotherSubtype() {
+        Sub1 sub1 = new Sub1();
+        Sub2 sub2 = new Sub2();
+
+        sub1.fUpdater.set(sub1, "f");
+        try {
+            sub1.fUpdater.set(sub2, "g");
+            shouldThrow();
+        }
+        catch (RuntimeException rt) {}
+    }
+
     /**
      *  get returns the last value set or assigned
      */
@@ -76,9 +97,8 @@
 	assertEquals(one,a.get(this));
 	a.set(this,two);
 	assertEquals(two,a.get(this));
-	a.set(this,-3);
-	assertEquals(-3,a.get(this).intValue());
-	
+	a.set(this,m3);
+	assertEquals(m3,a.get(this));
     }
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails

Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicReferenceTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicReferenceTest.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicReferenceTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/AtomicReferenceTest.java Tue Jul 28 09:30:33 2009
@@ -44,7 +44,7 @@
 	assertEquals(two,ai.get());
 	ai.set(m3);
 	assertEquals(m3,ai.get());
-	
+
     }
     /**
      * compareAndSet succeeds in changing value if equal to expected else fails

Modified: harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/ConcurrentHashMapTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/ConcurrentHashMapTest.java?rev=798469&r1=798468&r2=798469&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/ConcurrentHashMapTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/concurrent/src/test/java/ConcurrentHashMapTest.java Tue Jul 28 09:30:33 2009
@@ -81,8 +81,8 @@
      */
     public void testContainsValue() {
         ConcurrentHashMap map = map5();
-	assertTrue(map.contains("A"));
-        assertFalse(map.contains("Z"));
+	assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
     }
 
     /**
@@ -150,6 +150,49 @@
     }
 
     /**
+     *  keySet.toArray returns contains all keys
+     */
+    public void testKeySetToArray() {
+        ConcurrentHashMap map = map5();
+	Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+	assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     *  Values.toArray contains all values
+     */
+    public void testValuesToArray() {
+        ConcurrentHashMap map = map5();
+	Collection v = map.values();
+        Object[] ar = v.toArray();
+        ArrayList s = new ArrayList(Arrays.asList(ar));
+	assertEquals(5, ar.length);
+	assertTrue(s.contains("A"));
+	assertTrue(s.contains("B"));
+	assertTrue(s.contains("C"));
+	assertTrue(s.contains("D"));
+	assertTrue(s.contains("E"));
+    }
+
+    /**
+     *  entrySet.toArray contains all entries
+     */
+    public void testEntrySetToArray() {
+        ConcurrentHashMap map = map5();
+	Set s = map.entrySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+            assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+        }
+    }
+
+    /**
      * values collection contains all values
      */
     public void testValues() {
@@ -501,6 +544,19 @@
     }
 
     /**
+     * remove(x, null) returns false
+     */
+    public void testRemove3() {
+        try {
+            ConcurrentHashMap c = new ConcurrentHashMap(5);
+            c.put("sadsdf", "asdads");
+            assertFalse(c.remove("sadsdf", null));
+        } catch(NullPointerException e){
+            fail();
+        }
+    }
+
+    /**
      * A deserialized map equals original
      */
     public void testSerialization() {