rt/emul/compact/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
branchjdk7-b147
changeset 1890 212417b74b72
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java	Sat Mar 19 10:46:31 2016 +0100
     1.3 @@ -0,0 +1,1486 @@
     1.4 +/*
     1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.6 + *
     1.7 + * This code is free software; you can redistribute it and/or modify it
     1.8 + * under the terms of the GNU General Public License version 2 only, as
     1.9 + * published by the Free Software Foundation.  Oracle designates this
    1.10 + * particular file as subject to the "Classpath" exception as provided
    1.11 + * by Oracle in the LICENSE file that accompanied this code.
    1.12 + *
    1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.16 + * version 2 for more details (a copy is included in the LICENSE file that
    1.17 + * accompanied this code).
    1.18 + *
    1.19 + * You should have received a copy of the GNU General Public License version
    1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.22 + *
    1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.24 + * or visit www.oracle.com if you need additional information or have any
    1.25 + * questions.
    1.26 + */
    1.27 +
    1.28 +/*
    1.29 + * This file is available under and governed by the GNU General Public
    1.30 + * License version 2 only, as published by the Free Software Foundation.
    1.31 + * However, the following notice accompanied the original version of this
    1.32 + * file:
    1.33 + *
    1.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
    1.35 + * Expert Group and released to the public domain, as explained at
    1.36 + * http://creativecommons.org/publicdomain/zero/1.0/
    1.37 + */
    1.38 +
    1.39 +package java.util.concurrent.locks;
    1.40 +import java.util.concurrent.*;
    1.41 +import java.util.concurrent.atomic.*;
    1.42 +import java.util.*;
    1.43 +
    1.44 +/**
    1.45 + * An implementation of {@link ReadWriteLock} supporting similar
    1.46 + * semantics to {@link ReentrantLock}.
    1.47 + * <p>This class has the following properties:
    1.48 + *
    1.49 + * <ul>
    1.50 + * <li><b>Acquisition order</b>
    1.51 + *
    1.52 + * <p> This class does not impose a reader or writer preference
    1.53 + * ordering for lock access.  However, it does support an optional
    1.54 + * <em>fairness</em> policy.
    1.55 + *
    1.56 + * <dl>
    1.57 + * <dt><b><i>Non-fair mode (default)</i></b>
    1.58 + * <dd>When constructed as non-fair (the default), the order of entry
    1.59 + * to the read and write lock is unspecified, subject to reentrancy
    1.60 + * constraints.  A nonfair lock that is continuously contended may
    1.61 + * indefinitely postpone one or more reader or writer threads, but
    1.62 + * will normally have higher throughput than a fair lock.
    1.63 + * <p>
    1.64 + *
    1.65 + * <dt><b><i>Fair mode</i></b>
    1.66 + * <dd> When constructed as fair, threads contend for entry using an
    1.67 + * approximately arrival-order policy. When the currently held lock
    1.68 + * is released either the longest-waiting single writer thread will
    1.69 + * be assigned the write lock, or if there is a group of reader threads
    1.70 + * waiting longer than all waiting writer threads, that group will be
    1.71 + * assigned the read lock.
    1.72 + *
    1.73 + * <p>A thread that tries to acquire a fair read lock (non-reentrantly)
    1.74 + * will block if either the write lock is held, or there is a waiting
    1.75 + * writer thread. The thread will not acquire the read lock until
    1.76 + * after the oldest currently waiting writer thread has acquired and
    1.77 + * released the write lock. Of course, if a waiting writer abandons
    1.78 + * its wait, leaving one or more reader threads as the longest waiters
    1.79 + * in the queue with the write lock free, then those readers will be
    1.80 + * assigned the read lock.
    1.81 + *
    1.82 + * <p>A thread that tries to acquire a fair write lock (non-reentrantly)
    1.83 + * will block unless both the read lock and write lock are free (which
    1.84 + * implies there are no waiting threads).  (Note that the non-blocking
    1.85 + * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
    1.86 + * do not honor this fair setting and will acquire the lock if it is
    1.87 + * possible, regardless of waiting threads.)
    1.88 + * <p>
    1.89 + * </dl>
    1.90 + *
    1.91 + * <li><b>Reentrancy</b>
    1.92 + *
    1.93 + * <p>This lock allows both readers and writers to reacquire read or
    1.94 + * write locks in the style of a {@link ReentrantLock}. Non-reentrant
    1.95 + * readers are not allowed until all write locks held by the writing
    1.96 + * thread have been released.
    1.97 + *
    1.98 + * <p>Additionally, a writer can acquire the read lock, but not
    1.99 + * vice-versa.  Among other applications, reentrancy can be useful
   1.100 + * when write locks are held during calls or callbacks to methods that
   1.101 + * perform reads under read locks.  If a reader tries to acquire the
   1.102 + * write lock it will never succeed.
   1.103 + *
   1.104 + * <li><b>Lock downgrading</b>
   1.105 + * <p>Reentrancy also allows downgrading from the write lock to a read lock,
   1.106 + * by acquiring the write lock, then the read lock and then releasing the
   1.107 + * write lock. However, upgrading from a read lock to the write lock is
   1.108 + * <b>not</b> possible.
   1.109 + *
   1.110 + * <li><b>Interruption of lock acquisition</b>
   1.111 + * <p>The read lock and write lock both support interruption during lock
   1.112 + * acquisition.
   1.113 + *
   1.114 + * <li><b>{@link Condition} support</b>
   1.115 + * <p>The write lock provides a {@link Condition} implementation that
   1.116 + * behaves in the same way, with respect to the write lock, as the
   1.117 + * {@link Condition} implementation provided by
   1.118 + * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
   1.119 + * This {@link Condition} can, of course, only be used with the write lock.
   1.120 + *
   1.121 + * <p>The read lock does not support a {@link Condition} and
   1.122 + * {@code readLock().newCondition()} throws
   1.123 + * {@code UnsupportedOperationException}.
   1.124 + *
   1.125 + * <li><b>Instrumentation</b>
   1.126 + * <p>This class supports methods to determine whether locks
   1.127 + * are held or contended. These methods are designed for monitoring
   1.128 + * system state, not for synchronization control.
   1.129 + * </ul>
   1.130 + *
   1.131 + * <p>Serialization of this class behaves in the same way as built-in
   1.132 + * locks: a deserialized lock is in the unlocked state, regardless of
   1.133 + * its state when serialized.
   1.134 + *
   1.135 + * <p><b>Sample usages</b>. Here is a code sketch showing how to perform
   1.136 + * lock downgrading after updating a cache (exception handling is
   1.137 + * particularly tricky when handling multiple locks in a non-nested
   1.138 + * fashion):
   1.139 + *
   1.140 + * <pre> {@code
   1.141 + * class CachedData {
   1.142 + *   Object data;
   1.143 + *   volatile boolean cacheValid;
   1.144 + *   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
   1.145 + *
   1.146 + *   void processCachedData() {
   1.147 + *     rwl.readLock().lock();
   1.148 + *     if (!cacheValid) {
   1.149 + *        // Must release read lock before acquiring write lock
   1.150 + *        rwl.readLock().unlock();
   1.151 + *        rwl.writeLock().lock();
   1.152 + *        try {
   1.153 + *          // Recheck state because another thread might have
   1.154 + *          // acquired write lock and changed state before we did.
   1.155 + *          if (!cacheValid) {
   1.156 + *            data = ...
   1.157 + *            cacheValid = true;
   1.158 + *          }
   1.159 + *          // Downgrade by acquiring read lock before releasing write lock
   1.160 + *          rwl.readLock().lock();
   1.161 + *        } finally {
   1.162 + *          rwl.writeLock().unlock(); // Unlock write, still hold read
   1.163 + *        }
   1.164 + *     }
   1.165 + *
   1.166 + *     try {
   1.167 + *       use(data);
   1.168 + *     } finally {
   1.169 + *       rwl.readLock().unlock();
   1.170 + *     }
   1.171 + *   }
   1.172 + * }}</pre>
   1.173 + *
   1.174 + * ReentrantReadWriteLocks can be used to improve concurrency in some
   1.175 + * uses of some kinds of Collections. This is typically worthwhile
   1.176 + * only when the collections are expected to be large, accessed by
   1.177 + * more reader threads than writer threads, and entail operations with
   1.178 + * overhead that outweighs synchronization overhead. For example, here
   1.179 + * is a class using a TreeMap that is expected to be large and
   1.180 + * concurrently accessed.
   1.181 + *
   1.182 + * <pre>{@code
   1.183 + * class RWDictionary {
   1.184 + *    private final Map<String, Data> m = new TreeMap<String, Data>();
   1.185 + *    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
   1.186 + *    private final Lock r = rwl.readLock();
   1.187 + *    private final Lock w = rwl.writeLock();
   1.188 + *
   1.189 + *    public Data get(String key) {
   1.190 + *        r.lock();
   1.191 + *        try { return m.get(key); }
   1.192 + *        finally { r.unlock(); }
   1.193 + *    }
   1.194 + *    public String[] allKeys() {
   1.195 + *        r.lock();
   1.196 + *        try { return m.keySet().toArray(); }
   1.197 + *        finally { r.unlock(); }
   1.198 + *    }
   1.199 + *    public Data put(String key, Data value) {
   1.200 + *        w.lock();
   1.201 + *        try { return m.put(key, value); }
   1.202 + *        finally { w.unlock(); }
   1.203 + *    }
   1.204 + *    public void clear() {
   1.205 + *        w.lock();
   1.206 + *        try { m.clear(); }
   1.207 + *        finally { w.unlock(); }
   1.208 + *    }
   1.209 + * }}</pre>
   1.210 + *
   1.211 + * <h3>Implementation Notes</h3>
   1.212 + *
   1.213 + * <p>This lock supports a maximum of 65535 recursive write locks
   1.214 + * and 65535 read locks. Attempts to exceed these limits result in
   1.215 + * {@link Error} throws from locking methods.
   1.216 + *
   1.217 + * @since 1.5
   1.218 + * @author Doug Lea
   1.219 + *
   1.220 + */
   1.221 +public class ReentrantReadWriteLock
   1.222 +        implements ReadWriteLock, java.io.Serializable {
   1.223 +    private static final long serialVersionUID = -6992448646407690164L;
   1.224 +    /** Inner class providing readlock */
   1.225 +    private final ReentrantReadWriteLock.ReadLock readerLock;
   1.226 +    /** Inner class providing writelock */
   1.227 +    private final ReentrantReadWriteLock.WriteLock writerLock;
   1.228 +    /** Performs all synchronization mechanics */
   1.229 +    final Sync sync;
   1.230 +
   1.231 +    /**
   1.232 +     * Creates a new {@code ReentrantReadWriteLock} with
   1.233 +     * default (nonfair) ordering properties.
   1.234 +     */
   1.235 +    public ReentrantReadWriteLock() {
   1.236 +        this(false);
   1.237 +    }
   1.238 +
   1.239 +    /**
   1.240 +     * Creates a new {@code ReentrantReadWriteLock} with
   1.241 +     * the given fairness policy.
   1.242 +     *
   1.243 +     * @param fair {@code true} if this lock should use a fair ordering policy
   1.244 +     */
   1.245 +    public ReentrantReadWriteLock(boolean fair) {
   1.246 +        sync = fair ? new FairSync() : new NonfairSync();
   1.247 +        readerLock = new ReadLock(this);
   1.248 +        writerLock = new WriteLock(this);
   1.249 +    }
   1.250 +
   1.251 +    public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
   1.252 +    public ReentrantReadWriteLock.ReadLock  readLock()  { return readerLock; }
   1.253 +
   1.254 +    /**
   1.255 +     * Synchronization implementation for ReentrantReadWriteLock.
   1.256 +     * Subclassed into fair and nonfair versions.
   1.257 +     */
   1.258 +    abstract static class Sync extends AbstractQueuedSynchronizer {
   1.259 +        private static final long serialVersionUID = 6317671515068378041L;
   1.260 +
   1.261 +        /*
   1.262 +         * Read vs write count extraction constants and functions.
   1.263 +         * Lock state is logically divided into two unsigned shorts:
   1.264 +         * The lower one representing the exclusive (writer) lock hold count,
   1.265 +         * and the upper the shared (reader) hold count.
   1.266 +         */
   1.267 +
   1.268 +        static final int SHARED_SHIFT   = 16;
   1.269 +        static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
   1.270 +        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
   1.271 +        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
   1.272 +
   1.273 +        /** Returns the number of shared holds represented in count  */
   1.274 +        static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
   1.275 +        /** Returns the number of exclusive holds represented in count  */
   1.276 +        static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
   1.277 +
   1.278 +        /**
   1.279 +         * A counter for per-thread read hold counts.
   1.280 +         * Maintained as a ThreadLocal; cached in cachedHoldCounter
   1.281 +         */
   1.282 +        static final class HoldCounter {
   1.283 +            int count = 0;
   1.284 +            // Use id, not reference, to avoid garbage retention
   1.285 +            final long tid = Thread.currentThread().getId();
   1.286 +        }
   1.287 +
   1.288 +        /**
   1.289 +         * ThreadLocal subclass. Easiest to explicitly define for sake
   1.290 +         * of deserialization mechanics.
   1.291 +         */
   1.292 +        static final class ThreadLocalHoldCounter
   1.293 +            extends ThreadLocal<HoldCounter> {
   1.294 +            public HoldCounter initialValue() {
   1.295 +                return new HoldCounter();
   1.296 +            }
   1.297 +        }
   1.298 +
   1.299 +        /**
   1.300 +         * The number of reentrant read locks held by current thread.
   1.301 +         * Initialized only in constructor and readObject.
   1.302 +         * Removed whenever a thread's read hold count drops to 0.
   1.303 +         */
   1.304 +        private transient ThreadLocalHoldCounter readHolds;
   1.305 +
   1.306 +        /**
   1.307 +         * The hold count of the last thread to successfully acquire
   1.308 +         * readLock. This saves ThreadLocal lookup in the common case
   1.309 +         * where the next thread to release is the last one to
   1.310 +         * acquire. This is non-volatile since it is just used
   1.311 +         * as a heuristic, and would be great for threads to cache.
   1.312 +         *
   1.313 +         * <p>Can outlive the Thread for which it is caching the read
   1.314 +         * hold count, but avoids garbage retention by not retaining a
   1.315 +         * reference to the Thread.
   1.316 +         *
   1.317 +         * <p>Accessed via a benign data race; relies on the memory
   1.318 +         * model's final field and out-of-thin-air guarantees.
   1.319 +         */
   1.320 +        private transient HoldCounter cachedHoldCounter;
   1.321 +
   1.322 +        /**
   1.323 +         * firstReader is the first thread to have acquired the read lock.
   1.324 +         * firstReaderHoldCount is firstReader's hold count.
   1.325 +         *
   1.326 +         * <p>More precisely, firstReader is the unique thread that last
   1.327 +         * changed the shared count from 0 to 1, and has not released the
   1.328 +         * read lock since then; null if there is no such thread.
   1.329 +         *
   1.330 +         * <p>Cannot cause garbage retention unless the thread terminated
   1.331 +         * without relinquishing its read locks, since tryReleaseShared
   1.332 +         * sets it to null.
   1.333 +         *
   1.334 +         * <p>Accessed via a benign data race; relies on the memory
   1.335 +         * model's out-of-thin-air guarantees for references.
   1.336 +         *
   1.337 +         * <p>This allows tracking of read holds for uncontended read
   1.338 +         * locks to be very cheap.
   1.339 +         */
   1.340 +        private transient Thread firstReader = null;
   1.341 +        private transient int firstReaderHoldCount;
   1.342 +
   1.343 +        Sync() {
   1.344 +            readHolds = new ThreadLocalHoldCounter();
   1.345 +            setState(getState()); // ensures visibility of readHolds
   1.346 +        }
   1.347 +
   1.348 +        /*
   1.349 +         * Acquires and releases use the same code for fair and
   1.350 +         * nonfair locks, but differ in whether/how they allow barging
   1.351 +         * when queues are non-empty.
   1.352 +         */
   1.353 +
   1.354 +        /**
   1.355 +         * Returns true if the current thread, when trying to acquire
   1.356 +         * the read lock, and otherwise eligible to do so, should block
   1.357 +         * because of policy for overtaking other waiting threads.
   1.358 +         */
   1.359 +        abstract boolean readerShouldBlock();
   1.360 +
   1.361 +        /**
   1.362 +         * Returns true if the current thread, when trying to acquire
   1.363 +         * the write lock, and otherwise eligible to do so, should block
   1.364 +         * because of policy for overtaking other waiting threads.
   1.365 +         */
   1.366 +        abstract boolean writerShouldBlock();
   1.367 +
   1.368 +        /*
   1.369 +         * Note that tryRelease and tryAcquire can be called by
   1.370 +         * Conditions. So it is possible that their arguments contain
   1.371 +         * both read and write holds that are all released during a
   1.372 +         * condition wait and re-established in tryAcquire.
   1.373 +         */
   1.374 +
   1.375 +        protected final boolean tryRelease(int releases) {
   1.376 +            if (!isHeldExclusively())
   1.377 +                throw new IllegalMonitorStateException();
   1.378 +            int nextc = getState() - releases;
   1.379 +            boolean free = exclusiveCount(nextc) == 0;
   1.380 +            if (free)
   1.381 +                setExclusiveOwnerThread(null);
   1.382 +            setState(nextc);
   1.383 +            return free;
   1.384 +        }
   1.385 +
   1.386 +        protected final boolean tryAcquire(int acquires) {
   1.387 +            /*
   1.388 +             * Walkthrough:
   1.389 +             * 1. If read count nonzero or write count nonzero
   1.390 +             *    and owner is a different thread, fail.
   1.391 +             * 2. If count would saturate, fail. (This can only
   1.392 +             *    happen if count is already nonzero.)
   1.393 +             * 3. Otherwise, this thread is eligible for lock if
   1.394 +             *    it is either a reentrant acquire or
   1.395 +             *    queue policy allows it. If so, update state
   1.396 +             *    and set owner.
   1.397 +             */
   1.398 +            Thread current = Thread.currentThread();
   1.399 +            int c = getState();
   1.400 +            int w = exclusiveCount(c);
   1.401 +            if (c != 0) {
   1.402 +                // (Note: if c != 0 and w == 0 then shared count != 0)
   1.403 +                if (w == 0 || current != getExclusiveOwnerThread())
   1.404 +                    return false;
   1.405 +                if (w + exclusiveCount(acquires) > MAX_COUNT)
   1.406 +                    throw new Error("Maximum lock count exceeded");
   1.407 +                // Reentrant acquire
   1.408 +                setState(c + acquires);
   1.409 +                return true;
   1.410 +            }
   1.411 +            if (writerShouldBlock() ||
   1.412 +                !compareAndSetState(c, c + acquires))
   1.413 +                return false;
   1.414 +            setExclusiveOwnerThread(current);
   1.415 +            return true;
   1.416 +        }
   1.417 +
   1.418 +        protected final boolean tryReleaseShared(int unused) {
   1.419 +            Thread current = Thread.currentThread();
   1.420 +            if (firstReader == current) {
   1.421 +                // assert firstReaderHoldCount > 0;
   1.422 +                if (firstReaderHoldCount == 1)
   1.423 +                    firstReader = null;
   1.424 +                else
   1.425 +                    firstReaderHoldCount--;
   1.426 +            } else {
   1.427 +                HoldCounter rh = cachedHoldCounter;
   1.428 +                if (rh == null || rh.tid != current.getId())
   1.429 +                    rh = readHolds.get();
   1.430 +                int count = rh.count;
   1.431 +                if (count <= 1) {
   1.432 +                    readHolds.remove();
   1.433 +                    if (count <= 0)
   1.434 +                        throw unmatchedUnlockException();
   1.435 +                }
   1.436 +                --rh.count;
   1.437 +            }
   1.438 +            for (;;) {
   1.439 +                int c = getState();
   1.440 +                int nextc = c - SHARED_UNIT;
   1.441 +                if (compareAndSetState(c, nextc))
   1.442 +                    // Releasing the read lock has no effect on readers,
   1.443 +                    // but it may allow waiting writers to proceed if
   1.444 +                    // both read and write locks are now free.
   1.445 +                    return nextc == 0;
   1.446 +            }
   1.447 +        }
   1.448 +
   1.449 +        private IllegalMonitorStateException unmatchedUnlockException() {
   1.450 +            return new IllegalMonitorStateException(
   1.451 +                "attempt to unlock read lock, not locked by current thread");
   1.452 +        }
   1.453 +
   1.454 +        protected final int tryAcquireShared(int unused) {
   1.455 +            /*
   1.456 +             * Walkthrough:
   1.457 +             * 1. If write lock held by another thread, fail.
   1.458 +             * 2. Otherwise, this thread is eligible for
   1.459 +             *    lock wrt state, so ask if it should block
   1.460 +             *    because of queue policy. If not, try
   1.461 +             *    to grant by CASing state and updating count.
   1.462 +             *    Note that step does not check for reentrant
   1.463 +             *    acquires, which is postponed to full version
   1.464 +             *    to avoid having to check hold count in
   1.465 +             *    the more typical non-reentrant case.
   1.466 +             * 3. If step 2 fails either because thread
   1.467 +             *    apparently not eligible or CAS fails or count
   1.468 +             *    saturated, chain to version with full retry loop.
   1.469 +             */
   1.470 +            Thread current = Thread.currentThread();
   1.471 +            int c = getState();
   1.472 +            if (exclusiveCount(c) != 0 &&
   1.473 +                getExclusiveOwnerThread() != current)
   1.474 +                return -1;
   1.475 +            int r = sharedCount(c);
   1.476 +            if (!readerShouldBlock() &&
   1.477 +                r < MAX_COUNT &&
   1.478 +                compareAndSetState(c, c + SHARED_UNIT)) {
   1.479 +                if (r == 0) {
   1.480 +                    firstReader = current;
   1.481 +                    firstReaderHoldCount = 1;
   1.482 +                } else if (firstReader == current) {
   1.483 +                    firstReaderHoldCount++;
   1.484 +                } else {
   1.485 +                    HoldCounter rh = cachedHoldCounter;
   1.486 +                    if (rh == null || rh.tid != current.getId())
   1.487 +                        cachedHoldCounter = rh = readHolds.get();
   1.488 +                    else if (rh.count == 0)
   1.489 +                        readHolds.set(rh);
   1.490 +                    rh.count++;
   1.491 +                }
   1.492 +                return 1;
   1.493 +            }
   1.494 +            return fullTryAcquireShared(current);
   1.495 +        }
   1.496 +
   1.497 +        /**
   1.498 +         * Full version of acquire for reads, that handles CAS misses
   1.499 +         * and reentrant reads not dealt with in tryAcquireShared.
   1.500 +         */
   1.501 +        final int fullTryAcquireShared(Thread current) {
   1.502 +            /*
   1.503 +             * This code is in part redundant with that in
   1.504 +             * tryAcquireShared but is simpler overall by not
   1.505 +             * complicating tryAcquireShared with interactions between
   1.506 +             * retries and lazily reading hold counts.
   1.507 +             */
   1.508 +            HoldCounter rh = null;
   1.509 +            for (;;) {
   1.510 +                int c = getState();
   1.511 +                if (exclusiveCount(c) != 0) {
   1.512 +                    if (getExclusiveOwnerThread() != current)
   1.513 +                        return -1;
   1.514 +                    // else we hold the exclusive lock; blocking here
   1.515 +                    // would cause deadlock.
   1.516 +                } else if (readerShouldBlock()) {
   1.517 +                    // Make sure we're not acquiring read lock reentrantly
   1.518 +                    if (firstReader == current) {
   1.519 +                        // assert firstReaderHoldCount > 0;
   1.520 +                    } else {
   1.521 +                        if (rh == null) {
   1.522 +                            rh = cachedHoldCounter;
   1.523 +                            if (rh == null || rh.tid != current.getId()) {
   1.524 +                                rh = readHolds.get();
   1.525 +                                if (rh.count == 0)
   1.526 +                                    readHolds.remove();
   1.527 +                            }
   1.528 +                        }
   1.529 +                        if (rh.count == 0)
   1.530 +                            return -1;
   1.531 +                    }
   1.532 +                }
   1.533 +                if (sharedCount(c) == MAX_COUNT)
   1.534 +                    throw new Error("Maximum lock count exceeded");
   1.535 +                if (compareAndSetState(c, c + SHARED_UNIT)) {
   1.536 +                    if (sharedCount(c) == 0) {
   1.537 +                        firstReader = current;
   1.538 +                        firstReaderHoldCount = 1;
   1.539 +                    } else if (firstReader == current) {
   1.540 +                        firstReaderHoldCount++;
   1.541 +                    } else {
   1.542 +                        if (rh == null)
   1.543 +                            rh = cachedHoldCounter;
   1.544 +                        if (rh == null || rh.tid != current.getId())
   1.545 +                            rh = readHolds.get();
   1.546 +                        else if (rh.count == 0)
   1.547 +                            readHolds.set(rh);
   1.548 +                        rh.count++;
   1.549 +                        cachedHoldCounter = rh; // cache for release
   1.550 +                    }
   1.551 +                    return 1;
   1.552 +                }
   1.553 +            }
   1.554 +        }
   1.555 +
   1.556 +        /**
   1.557 +         * Performs tryLock for write, enabling barging in both modes.
   1.558 +         * This is identical in effect to tryAcquire except for lack
   1.559 +         * of calls to writerShouldBlock.
   1.560 +         */
   1.561 +        final boolean tryWriteLock() {
   1.562 +            Thread current = Thread.currentThread();
   1.563 +            int c = getState();
   1.564 +            if (c != 0) {
   1.565 +                int w = exclusiveCount(c);
   1.566 +                if (w == 0 || current != getExclusiveOwnerThread())
   1.567 +                    return false;
   1.568 +                if (w == MAX_COUNT)
   1.569 +                    throw new Error("Maximum lock count exceeded");
   1.570 +            }
   1.571 +            if (!compareAndSetState(c, c + 1))
   1.572 +                return false;
   1.573 +            setExclusiveOwnerThread(current);
   1.574 +            return true;
   1.575 +        }
   1.576 +
   1.577 +        /**
   1.578 +         * Performs tryLock for read, enabling barging in both modes.
   1.579 +         * This is identical in effect to tryAcquireShared except for
   1.580 +         * lack of calls to readerShouldBlock.
   1.581 +         */
   1.582 +        final boolean tryReadLock() {
   1.583 +            Thread current = Thread.currentThread();
   1.584 +            for (;;) {
   1.585 +                int c = getState();
   1.586 +                if (exclusiveCount(c) != 0 &&
   1.587 +                    getExclusiveOwnerThread() != current)
   1.588 +                    return false;
   1.589 +                int r = sharedCount(c);
   1.590 +                if (r == MAX_COUNT)
   1.591 +                    throw new Error("Maximum lock count exceeded");
   1.592 +                if (compareAndSetState(c, c + SHARED_UNIT)) {
   1.593 +                    if (r == 0) {
   1.594 +                        firstReader = current;
   1.595 +                        firstReaderHoldCount = 1;
   1.596 +                    } else if (firstReader == current) {
   1.597 +                        firstReaderHoldCount++;
   1.598 +                    } else {
   1.599 +                        HoldCounter rh = cachedHoldCounter;
   1.600 +                        if (rh == null || rh.tid != current.getId())
   1.601 +                            cachedHoldCounter = rh = readHolds.get();
   1.602 +                        else if (rh.count == 0)
   1.603 +                            readHolds.set(rh);
   1.604 +                        rh.count++;
   1.605 +                    }
   1.606 +                    return true;
   1.607 +                }
   1.608 +            }
   1.609 +        }
   1.610 +
   1.611 +        protected final boolean isHeldExclusively() {
   1.612 +            // While we must in general read state before owner,
   1.613 +            // we don't need to do so to check if current thread is owner
   1.614 +            return getExclusiveOwnerThread() == Thread.currentThread();
   1.615 +        }
   1.616 +
   1.617 +        // Methods relayed to outer class
   1.618 +
   1.619 +        final ConditionObject newCondition() {
   1.620 +            return new ConditionObject();
   1.621 +        }
   1.622 +
   1.623 +        final Thread getOwner() {
   1.624 +            // Must read state before owner to ensure memory consistency
   1.625 +            return ((exclusiveCount(getState()) == 0) ?
   1.626 +                    null :
   1.627 +                    getExclusiveOwnerThread());
   1.628 +        }
   1.629 +
   1.630 +        final int getReadLockCount() {
   1.631 +            return sharedCount(getState());
   1.632 +        }
   1.633 +
   1.634 +        final boolean isWriteLocked() {
   1.635 +            return exclusiveCount(getState()) != 0;
   1.636 +        }
   1.637 +
   1.638 +        final int getWriteHoldCount() {
   1.639 +            return isHeldExclusively() ? exclusiveCount(getState()) : 0;
   1.640 +        }
   1.641 +
   1.642 +        final int getReadHoldCount() {
   1.643 +            if (getReadLockCount() == 0)
   1.644 +                return 0;
   1.645 +
   1.646 +            Thread current = Thread.currentThread();
   1.647 +            if (firstReader == current)
   1.648 +                return firstReaderHoldCount;
   1.649 +
   1.650 +            HoldCounter rh = cachedHoldCounter;
   1.651 +            if (rh != null && rh.tid == current.getId())
   1.652 +                return rh.count;
   1.653 +
   1.654 +            int count = readHolds.get().count;
   1.655 +            if (count == 0) readHolds.remove();
   1.656 +            return count;
   1.657 +        }
   1.658 +
   1.659 +        /**
   1.660 +         * Reconstitute this lock instance from a stream
   1.661 +         * @param s the stream
   1.662 +         */
   1.663 +        private void readObject(java.io.ObjectInputStream s)
   1.664 +            throws java.io.IOException, ClassNotFoundException {
   1.665 +            s.defaultReadObject();
   1.666 +            readHolds = new ThreadLocalHoldCounter();
   1.667 +            setState(0); // reset to unlocked state
   1.668 +        }
   1.669 +
   1.670 +        final int getCount() { return getState(); }
   1.671 +    }
   1.672 +
   1.673 +    /**
   1.674 +     * Nonfair version of Sync
   1.675 +     */
   1.676 +    static final class NonfairSync extends Sync {
   1.677 +        private static final long serialVersionUID = -8159625535654395037L;
   1.678 +        final boolean writerShouldBlock() {
   1.679 +            return false; // writers can always barge
   1.680 +        }
   1.681 +        final boolean readerShouldBlock() {
   1.682 +            /* As a heuristic to avoid indefinite writer starvation,
   1.683 +             * block if the thread that momentarily appears to be head
   1.684 +             * of queue, if one exists, is a waiting writer.  This is
   1.685 +             * only a probabilistic effect since a new reader will not
   1.686 +             * block if there is a waiting writer behind other enabled
   1.687 +             * readers that have not yet drained from the queue.
   1.688 +             */
   1.689 +            return apparentlyFirstQueuedIsExclusive();
   1.690 +        }
   1.691 +    }
   1.692 +
   1.693 +    /**
   1.694 +     * Fair version of Sync
   1.695 +     */
   1.696 +    static final class FairSync extends Sync {
   1.697 +        private static final long serialVersionUID = -2274990926593161451L;
   1.698 +        final boolean writerShouldBlock() {
   1.699 +            return hasQueuedPredecessors();
   1.700 +        }
   1.701 +        final boolean readerShouldBlock() {
   1.702 +            return hasQueuedPredecessors();
   1.703 +        }
   1.704 +    }
   1.705 +
   1.706 +    /**
   1.707 +     * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
   1.708 +     */
   1.709 +    public static class ReadLock implements Lock, java.io.Serializable {
   1.710 +        private static final long serialVersionUID = -5992448646407690164L;
   1.711 +        private final Sync sync;
   1.712 +
   1.713 +        /**
   1.714 +         * Constructor for use by subclasses
   1.715 +         *
   1.716 +         * @param lock the outer lock object
   1.717 +         * @throws NullPointerException if the lock is null
   1.718 +         */
   1.719 +        protected ReadLock(ReentrantReadWriteLock lock) {
   1.720 +            sync = lock.sync;
   1.721 +        }
   1.722 +
   1.723 +        /**
   1.724 +         * Acquires the read lock.
   1.725 +         *
   1.726 +         * <p>Acquires the read lock if the write lock is not held by
   1.727 +         * another thread and returns immediately.
   1.728 +         *
   1.729 +         * <p>If the write lock is held by another thread then
   1.730 +         * the current thread becomes disabled for thread scheduling
   1.731 +         * purposes and lies dormant until the read lock has been acquired.
   1.732 +         */
   1.733 +        public void lock() {
   1.734 +            sync.acquireShared(1);
   1.735 +        }
   1.736 +
   1.737 +        /**
   1.738 +         * Acquires the read lock unless the current thread is
   1.739 +         * {@linkplain Thread#interrupt interrupted}.
   1.740 +         *
   1.741 +         * <p>Acquires the read lock if the write lock is not held
   1.742 +         * by another thread and returns immediately.
   1.743 +         *
   1.744 +         * <p>If the write lock is held by another thread then the
   1.745 +         * current thread becomes disabled for thread scheduling
   1.746 +         * purposes and lies dormant until one of two things happens:
   1.747 +         *
   1.748 +         * <ul>
   1.749 +         *
   1.750 +         * <li>The read lock is acquired by the current thread; or
   1.751 +         *
   1.752 +         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   1.753 +         * the current thread.
   1.754 +         *
   1.755 +         * </ul>
   1.756 +         *
   1.757 +         * <p>If the current thread:
   1.758 +         *
   1.759 +         * <ul>
   1.760 +         *
   1.761 +         * <li>has its interrupted status set on entry to this method; or
   1.762 +         *
   1.763 +         * <li>is {@linkplain Thread#interrupt interrupted} while
   1.764 +         * acquiring the read lock,
   1.765 +         *
   1.766 +         * </ul>
   1.767 +         *
   1.768 +         * then {@link InterruptedException} is thrown and the current
   1.769 +         * thread's interrupted status is cleared.
   1.770 +         *
   1.771 +         * <p>In this implementation, as this method is an explicit
   1.772 +         * interruption point, preference is given to responding to
   1.773 +         * the interrupt over normal or reentrant acquisition of the
   1.774 +         * lock.
   1.775 +         *
   1.776 +         * @throws InterruptedException if the current thread is interrupted
   1.777 +         */
   1.778 +        public void lockInterruptibly() throws InterruptedException {
   1.779 +            sync.acquireSharedInterruptibly(1);
   1.780 +        }
   1.781 +
   1.782 +        /**
   1.783 +         * Acquires the read lock only if the write lock is not held by
   1.784 +         * another thread at the time of invocation.
   1.785 +         *
   1.786 +         * <p>Acquires the read lock if the write lock is not held by
   1.787 +         * another thread and returns immediately with the value
   1.788 +         * {@code true}. Even when this lock has been set to use a
   1.789 +         * fair ordering policy, a call to {@code tryLock()}
   1.790 +         * <em>will</em> immediately acquire the read lock if it is
   1.791 +         * available, whether or not other threads are currently
   1.792 +         * waiting for the read lock.  This &quot;barging&quot; behavior
   1.793 +         * can be useful in certain circumstances, even though it
   1.794 +         * breaks fairness. If you want to honor the fairness setting
   1.795 +         * for this lock, then use {@link #tryLock(long, TimeUnit)
   1.796 +         * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
   1.797 +         * (it also detects interruption).
   1.798 +         *
   1.799 +         * <p>If the write lock is held by another thread then
   1.800 +         * this method will return immediately with the value
   1.801 +         * {@code false}.
   1.802 +         *
   1.803 +         * @return {@code true} if the read lock was acquired
   1.804 +         */
   1.805 +        public  boolean tryLock() {
   1.806 +            return sync.tryReadLock();
   1.807 +        }
   1.808 +
   1.809 +        /**
   1.810 +         * Acquires the read lock if the write lock is not held by
   1.811 +         * another thread within the given waiting time and the
   1.812 +         * current thread has not been {@linkplain Thread#interrupt
   1.813 +         * interrupted}.
   1.814 +         *
   1.815 +         * <p>Acquires the read lock if the write lock is not held by
   1.816 +         * another thread and returns immediately with the value
   1.817 +         * {@code true}. If this lock has been set to use a fair
   1.818 +         * ordering policy then an available lock <em>will not</em> be
   1.819 +         * acquired if any other threads are waiting for the
   1.820 +         * lock. This is in contrast to the {@link #tryLock()}
   1.821 +         * method. If you want a timed {@code tryLock} that does
   1.822 +         * permit barging on a fair lock then combine the timed and
   1.823 +         * un-timed forms together:
   1.824 +         *
   1.825 +         * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
   1.826 +         * </pre>
   1.827 +         *
   1.828 +         * <p>If the write lock is held by another thread then the
   1.829 +         * current thread becomes disabled for thread scheduling
   1.830 +         * purposes and lies dormant until one of three things happens:
   1.831 +         *
   1.832 +         * <ul>
   1.833 +         *
   1.834 +         * <li>The read lock is acquired by the current thread; or
   1.835 +         *
   1.836 +         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   1.837 +         * the current thread; or
   1.838 +         *
   1.839 +         * <li>The specified waiting time elapses.
   1.840 +         *
   1.841 +         * </ul>
   1.842 +         *
   1.843 +         * <p>If the read lock is acquired then the value {@code true} is
   1.844 +         * returned.
   1.845 +         *
   1.846 +         * <p>If the current thread:
   1.847 +         *
   1.848 +         * <ul>
   1.849 +         *
   1.850 +         * <li>has its interrupted status set on entry to this method; or
   1.851 +         *
   1.852 +         * <li>is {@linkplain Thread#interrupt interrupted} while
   1.853 +         * acquiring the read lock,
   1.854 +         *
   1.855 +         * </ul> then {@link InterruptedException} is thrown and the
   1.856 +         * current thread's interrupted status is cleared.
   1.857 +         *
   1.858 +         * <p>If the specified waiting time elapses then the value
   1.859 +         * {@code false} is returned.  If the time is less than or
   1.860 +         * equal to zero, the method will not wait at all.
   1.861 +         *
   1.862 +         * <p>In this implementation, as this method is an explicit
   1.863 +         * interruption point, preference is given to responding to
   1.864 +         * the interrupt over normal or reentrant acquisition of the
   1.865 +         * lock, and over reporting the elapse of the waiting time.
   1.866 +         *
   1.867 +         * @param timeout the time to wait for the read lock
   1.868 +         * @param unit the time unit of the timeout argument
   1.869 +         * @return {@code true} if the read lock was acquired
   1.870 +         * @throws InterruptedException if the current thread is interrupted
   1.871 +         * @throws NullPointerException if the time unit is null
   1.872 +         *
   1.873 +         */
   1.874 +        public boolean tryLock(long timeout, TimeUnit unit)
   1.875 +                throws InterruptedException {
   1.876 +            return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
   1.877 +        }
   1.878 +
   1.879 +        /**
   1.880 +         * Attempts to release this lock.
   1.881 +         *
   1.882 +         * <p> If the number of readers is now zero then the lock
   1.883 +         * is made available for write lock attempts.
   1.884 +         */
   1.885 +        public  void unlock() {
   1.886 +            sync.releaseShared(1);
   1.887 +        }
   1.888 +
   1.889 +        /**
   1.890 +         * Throws {@code UnsupportedOperationException} because
   1.891 +         * {@code ReadLocks} do not support conditions.
   1.892 +         *
   1.893 +         * @throws UnsupportedOperationException always
   1.894 +         */
   1.895 +        public Condition newCondition() {
   1.896 +            throw new UnsupportedOperationException();
   1.897 +        }
   1.898 +
   1.899 +        /**
   1.900 +         * Returns a string identifying this lock, as well as its lock state.
   1.901 +         * The state, in brackets, includes the String {@code "Read locks ="}
   1.902 +         * followed by the number of held read locks.
   1.903 +         *
   1.904 +         * @return a string identifying this lock, as well as its lock state
   1.905 +         */
   1.906 +        public String toString() {
   1.907 +            int r = sync.getReadLockCount();
   1.908 +            return super.toString() +
   1.909 +                "[Read locks = " + r + "]";
   1.910 +        }
   1.911 +    }
   1.912 +
   1.913 +    /**
   1.914 +     * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
   1.915 +     */
   1.916 +    public static class WriteLock implements Lock, java.io.Serializable {
   1.917 +        private static final long serialVersionUID = -4992448646407690164L;
   1.918 +        private final Sync sync;
   1.919 +
   1.920 +        /**
   1.921 +         * Constructor for use by subclasses
   1.922 +         *
   1.923 +         * @param lock the outer lock object
   1.924 +         * @throws NullPointerException if the lock is null
   1.925 +         */
   1.926 +        protected WriteLock(ReentrantReadWriteLock lock) {
   1.927 +            sync = lock.sync;
   1.928 +        }
   1.929 +
   1.930 +        /**
   1.931 +         * Acquires the write lock.
   1.932 +         *
   1.933 +         * <p>Acquires the write lock if neither the read nor write lock
   1.934 +         * are held by another thread
   1.935 +         * and returns immediately, setting the write lock hold count to
   1.936 +         * one.
   1.937 +         *
   1.938 +         * <p>If the current thread already holds the write lock then the
   1.939 +         * hold count is incremented by one and the method returns
   1.940 +         * immediately.
   1.941 +         *
   1.942 +         * <p>If the lock is held by another thread then the current
   1.943 +         * thread becomes disabled for thread scheduling purposes and
   1.944 +         * lies dormant until the write lock has been acquired, at which
   1.945 +         * time the write lock hold count is set to one.
   1.946 +         */
   1.947 +        public void lock() {
   1.948 +            sync.acquire(1);
   1.949 +        }
   1.950 +
   1.951 +        /**
   1.952 +         * Acquires the write lock unless the current thread is
   1.953 +         * {@linkplain Thread#interrupt interrupted}.
   1.954 +         *
   1.955 +         * <p>Acquires the write lock if neither the read nor write lock
   1.956 +         * are held by another thread
   1.957 +         * and returns immediately, setting the write lock hold count to
   1.958 +         * one.
   1.959 +         *
   1.960 +         * <p>If the current thread already holds this lock then the
   1.961 +         * hold count is incremented by one and the method returns
   1.962 +         * immediately.
   1.963 +         *
   1.964 +         * <p>If the lock is held by another thread then the current
   1.965 +         * thread becomes disabled for thread scheduling purposes and
   1.966 +         * lies dormant until one of two things happens:
   1.967 +         *
   1.968 +         * <ul>
   1.969 +         *
   1.970 +         * <li>The write lock is acquired by the current thread; or
   1.971 +         *
   1.972 +         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   1.973 +         * the current thread.
   1.974 +         *
   1.975 +         * </ul>
   1.976 +         *
   1.977 +         * <p>If the write lock is acquired by the current thread then the
   1.978 +         * lock hold count is set to one.
   1.979 +         *
   1.980 +         * <p>If the current thread:
   1.981 +         *
   1.982 +         * <ul>
   1.983 +         *
   1.984 +         * <li>has its interrupted status set on entry to this method;
   1.985 +         * or
   1.986 +         *
   1.987 +         * <li>is {@linkplain Thread#interrupt interrupted} while
   1.988 +         * acquiring the write lock,
   1.989 +         *
   1.990 +         * </ul>
   1.991 +         *
   1.992 +         * then {@link InterruptedException} is thrown and the current
   1.993 +         * thread's interrupted status is cleared.
   1.994 +         *
   1.995 +         * <p>In this implementation, as this method is an explicit
   1.996 +         * interruption point, preference is given to responding to
   1.997 +         * the interrupt over normal or reentrant acquisition of the
   1.998 +         * lock.
   1.999 +         *
  1.1000 +         * @throws InterruptedException if the current thread is interrupted
  1.1001 +         */
  1.1002 +        public void lockInterruptibly() throws InterruptedException {
  1.1003 +            sync.acquireInterruptibly(1);
  1.1004 +        }
  1.1005 +
  1.1006 +        /**
  1.1007 +         * Acquires the write lock only if it is not held by another thread
  1.1008 +         * at the time of invocation.
  1.1009 +         *
  1.1010 +         * <p>Acquires the write lock if neither the read nor write lock
  1.1011 +         * are held by another thread
  1.1012 +         * and returns immediately with the value {@code true},
  1.1013 +         * setting the write lock hold count to one. Even when this lock has
  1.1014 +         * been set to use a fair ordering policy, a call to
  1.1015 +         * {@code tryLock()} <em>will</em> immediately acquire the
  1.1016 +         * lock if it is available, whether or not other threads are
  1.1017 +         * currently waiting for the write lock.  This &quot;barging&quot;
  1.1018 +         * behavior can be useful in certain circumstances, even
  1.1019 +         * though it breaks fairness. If you want to honor the
  1.1020 +         * fairness setting for this lock, then use {@link
  1.1021 +         * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
  1.1022 +         * which is almost equivalent (it also detects interruption).
  1.1023 +         *
  1.1024 +         * <p> If the current thread already holds this lock then the
  1.1025 +         * hold count is incremented by one and the method returns
  1.1026 +         * {@code true}.
  1.1027 +         *
  1.1028 +         * <p>If the lock is held by another thread then this method
  1.1029 +         * will return immediately with the value {@code false}.
  1.1030 +         *
  1.1031 +         * @return {@code true} if the lock was free and was acquired
  1.1032 +         * by the current thread, or the write lock was already held
  1.1033 +         * by the current thread; and {@code false} otherwise.
  1.1034 +         */
  1.1035 +        public boolean tryLock( ) {
  1.1036 +            return sync.tryWriteLock();
  1.1037 +        }
  1.1038 +
  1.1039 +        /**
  1.1040 +         * Acquires the write lock if it is not held by another thread
  1.1041 +         * within the given waiting time and the current thread has
  1.1042 +         * not been {@linkplain Thread#interrupt interrupted}.
  1.1043 +         *
  1.1044 +         * <p>Acquires the write lock if neither the read nor write lock
  1.1045 +         * are held by another thread
  1.1046 +         * and returns immediately with the value {@code true},
  1.1047 +         * setting the write lock hold count to one. If this lock has been
  1.1048 +         * set to use a fair ordering policy then an available lock
  1.1049 +         * <em>will not</em> be acquired if any other threads are
  1.1050 +         * waiting for the write lock. This is in contrast to the {@link
  1.1051 +         * #tryLock()} method. If you want a timed {@code tryLock}
  1.1052 +         * that does permit barging on a fair lock then combine the
  1.1053 +         * timed and un-timed forms together:
  1.1054 +         *
  1.1055 +         * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
  1.1056 +         * </pre>
  1.1057 +         *
  1.1058 +         * <p>If the current thread already holds this lock then the
  1.1059 +         * hold count is incremented by one and the method returns
  1.1060 +         * {@code true}.
  1.1061 +         *
  1.1062 +         * <p>If the lock is held by another thread then the current
  1.1063 +         * thread becomes disabled for thread scheduling purposes and
  1.1064 +         * lies dormant until one of three things happens:
  1.1065 +         *
  1.1066 +         * <ul>
  1.1067 +         *
  1.1068 +         * <li>The write lock is acquired by the current thread; or
  1.1069 +         *
  1.1070 +         * <li>Some other thread {@linkplain Thread#interrupt interrupts}
  1.1071 +         * the current thread; or
  1.1072 +         *
  1.1073 +         * <li>The specified waiting time elapses
  1.1074 +         *
  1.1075 +         * </ul>
  1.1076 +         *
  1.1077 +         * <p>If the write lock is acquired then the value {@code true} is
  1.1078 +         * returned and the write lock hold count is set to one.
  1.1079 +         *
  1.1080 +         * <p>If the current thread:
  1.1081 +         *
  1.1082 +         * <ul>
  1.1083 +         *
  1.1084 +         * <li>has its interrupted status set on entry to this method;
  1.1085 +         * or
  1.1086 +         *
  1.1087 +         * <li>is {@linkplain Thread#interrupt interrupted} while
  1.1088 +         * acquiring the write lock,
  1.1089 +         *
  1.1090 +         * </ul>
  1.1091 +         *
  1.1092 +         * then {@link InterruptedException} is thrown and the current
  1.1093 +         * thread's interrupted status is cleared.
  1.1094 +         *
  1.1095 +         * <p>If the specified waiting time elapses then the value
  1.1096 +         * {@code false} is returned.  If the time is less than or
  1.1097 +         * equal to zero, the method will not wait at all.
  1.1098 +         *
  1.1099 +         * <p>In this implementation, as this method is an explicit
  1.1100 +         * interruption point, preference is given to responding to
  1.1101 +         * the interrupt over normal or reentrant acquisition of the
  1.1102 +         * lock, and over reporting the elapse of the waiting time.
  1.1103 +         *
  1.1104 +         * @param timeout the time to wait for the write lock
  1.1105 +         * @param unit the time unit of the timeout argument
  1.1106 +         *
  1.1107 +         * @return {@code true} if the lock was free and was acquired
  1.1108 +         * by the current thread, or the write lock was already held by the
  1.1109 +         * current thread; and {@code false} if the waiting time
  1.1110 +         * elapsed before the lock could be acquired.
  1.1111 +         *
  1.1112 +         * @throws InterruptedException if the current thread is interrupted
  1.1113 +         * @throws NullPointerException if the time unit is null
  1.1114 +         *
  1.1115 +         */
  1.1116 +        public boolean tryLock(long timeout, TimeUnit unit)
  1.1117 +                throws InterruptedException {
  1.1118 +            return sync.tryAcquireNanos(1, unit.toNanos(timeout));
  1.1119 +        }
  1.1120 +
  1.1121 +        /**
  1.1122 +         * Attempts to release this lock.
  1.1123 +         *
  1.1124 +         * <p>If the current thread is the holder of this lock then
  1.1125 +         * the hold count is decremented. If the hold count is now
  1.1126 +         * zero then the lock is released.  If the current thread is
  1.1127 +         * not the holder of this lock then {@link
  1.1128 +         * IllegalMonitorStateException} is thrown.
  1.1129 +         *
  1.1130 +         * @throws IllegalMonitorStateException if the current thread does not
  1.1131 +         * hold this lock.
  1.1132 +         */
  1.1133 +        public void unlock() {
  1.1134 +            sync.release(1);
  1.1135 +        }
  1.1136 +
  1.1137 +        /**
  1.1138 +         * Returns a {@link Condition} instance for use with this
  1.1139 +         * {@link Lock} instance.
  1.1140 +         * <p>The returned {@link Condition} instance supports the same
  1.1141 +         * usages as do the {@link Object} monitor methods ({@link
  1.1142 +         * Object#wait() wait}, {@link Object#notify notify}, and {@link
  1.1143 +         * Object#notifyAll notifyAll}) when used with the built-in
  1.1144 +         * monitor lock.
  1.1145 +         *
  1.1146 +         * <ul>
  1.1147 +         *
  1.1148 +         * <li>If this write lock is not held when any {@link
  1.1149 +         * Condition} method is called then an {@link
  1.1150 +         * IllegalMonitorStateException} is thrown.  (Read locks are
  1.1151 +         * held independently of write locks, so are not checked or
  1.1152 +         * affected. However it is essentially always an error to
  1.1153 +         * invoke a condition waiting method when the current thread
  1.1154 +         * has also acquired read locks, since other threads that
  1.1155 +         * could unblock it will not be able to acquire the write
  1.1156 +         * lock.)
  1.1157 +         *
  1.1158 +         * <li>When the condition {@linkplain Condition#await() waiting}
  1.1159 +         * methods are called the write lock is released and, before
  1.1160 +         * they return, the write lock is reacquired and the lock hold
  1.1161 +         * count restored to what it was when the method was called.
  1.1162 +         *
  1.1163 +         * <li>If a thread is {@linkplain Thread#interrupt interrupted} while
  1.1164 +         * waiting then the wait will terminate, an {@link
  1.1165 +         * InterruptedException} will be thrown, and the thread's
  1.1166 +         * interrupted status will be cleared.
  1.1167 +         *
  1.1168 +         * <li> Waiting threads are signalled in FIFO order.
  1.1169 +         *
  1.1170 +         * <li>The ordering of lock reacquisition for threads returning
  1.1171 +         * from waiting methods is the same as for threads initially
  1.1172 +         * acquiring the lock, which is in the default case not specified,
  1.1173 +         * but for <em>fair</em> locks favors those threads that have been
  1.1174 +         * waiting the longest.
  1.1175 +         *
  1.1176 +         * </ul>
  1.1177 +         *
  1.1178 +         * @return the Condition object
  1.1179 +         */
  1.1180 +        public Condition newCondition() {
  1.1181 +            return sync.newCondition();
  1.1182 +        }
  1.1183 +
  1.1184 +        /**
  1.1185 +         * Returns a string identifying this lock, as well as its lock
  1.1186 +         * state.  The state, in brackets includes either the String
  1.1187 +         * {@code "Unlocked"} or the String {@code "Locked by"}
  1.1188 +         * followed by the {@linkplain Thread#getName name} of the owning thread.
  1.1189 +         *
  1.1190 +         * @return a string identifying this lock, as well as its lock state
  1.1191 +         */
  1.1192 +        public String toString() {
  1.1193 +            Thread o = sync.getOwner();
  1.1194 +            return super.toString() + ((o == null) ?
  1.1195 +                                       "[Unlocked]" :
  1.1196 +                                       "[Locked by thread " + o.getName() + "]");
  1.1197 +        }
  1.1198 +
  1.1199 +        /**
  1.1200 +         * Queries if this write lock is held by the current thread.
  1.1201 +         * Identical in effect to {@link
  1.1202 +         * ReentrantReadWriteLock#isWriteLockedByCurrentThread}.
  1.1203 +         *
  1.1204 +         * @return {@code true} if the current thread holds this lock and
  1.1205 +         *         {@code false} otherwise
  1.1206 +         * @since 1.6
  1.1207 +         */
  1.1208 +        public boolean isHeldByCurrentThread() {
  1.1209 +            return sync.isHeldExclusively();
  1.1210 +        }
  1.1211 +
  1.1212 +        /**
  1.1213 +         * Queries the number of holds on this write lock by the current
  1.1214 +         * thread.  A thread has a hold on a lock for each lock action
  1.1215 +         * that is not matched by an unlock action.  Identical in effect
  1.1216 +         * to {@link ReentrantReadWriteLock#getWriteHoldCount}.
  1.1217 +         *
  1.1218 +         * @return the number of holds on this lock by the current thread,
  1.1219 +         *         or zero if this lock is not held by the current thread
  1.1220 +         * @since 1.6
  1.1221 +         */
  1.1222 +        public int getHoldCount() {
  1.1223 +            return sync.getWriteHoldCount();
  1.1224 +        }
  1.1225 +    }
  1.1226 +
  1.1227 +    // Instrumentation and status
  1.1228 +
  1.1229 +    /**
  1.1230 +     * Returns {@code true} if this lock has fairness set true.
  1.1231 +     *
  1.1232 +     * @return {@code true} if this lock has fairness set true
  1.1233 +     */
  1.1234 +    public final boolean isFair() {
  1.1235 +        return sync instanceof FairSync;
  1.1236 +    }
  1.1237 +
  1.1238 +    /**
  1.1239 +     * Returns the thread that currently owns the write lock, or
  1.1240 +     * {@code null} if not owned. When this method is called by a
  1.1241 +     * thread that is not the owner, the return value reflects a
  1.1242 +     * best-effort approximation of current lock status. For example,
  1.1243 +     * the owner may be momentarily {@code null} even if there are
  1.1244 +     * threads trying to acquire the lock but have not yet done so.
  1.1245 +     * This method is designed to facilitate construction of
  1.1246 +     * subclasses that provide more extensive lock monitoring
  1.1247 +     * facilities.
  1.1248 +     *
  1.1249 +     * @return the owner, or {@code null} if not owned
  1.1250 +     */
  1.1251 +    protected Thread getOwner() {
  1.1252 +        return sync.getOwner();
  1.1253 +    }
  1.1254 +
  1.1255 +    /**
  1.1256 +     * Queries the number of read locks held for this lock. This
  1.1257 +     * method is designed for use in monitoring system state, not for
  1.1258 +     * synchronization control.
  1.1259 +     * @return the number of read locks held.
  1.1260 +     */
  1.1261 +    public int getReadLockCount() {
  1.1262 +        return sync.getReadLockCount();
  1.1263 +    }
  1.1264 +
  1.1265 +    /**
  1.1266 +     * Queries if the write lock is held by any thread. This method is
  1.1267 +     * designed for use in monitoring system state, not for
  1.1268 +     * synchronization control.
  1.1269 +     *
  1.1270 +     * @return {@code true} if any thread holds the write lock and
  1.1271 +     *         {@code false} otherwise
  1.1272 +     */
  1.1273 +    public boolean isWriteLocked() {
  1.1274 +        return sync.isWriteLocked();
  1.1275 +    }
  1.1276 +
  1.1277 +    /**
  1.1278 +     * Queries if the write lock is held by the current thread.
  1.1279 +     *
  1.1280 +     * @return {@code true} if the current thread holds the write lock and
  1.1281 +     *         {@code false} otherwise
  1.1282 +     */
  1.1283 +    public boolean isWriteLockedByCurrentThread() {
  1.1284 +        return sync.isHeldExclusively();
  1.1285 +    }
  1.1286 +
  1.1287 +    /**
  1.1288 +     * Queries the number of reentrant write holds on this lock by the
  1.1289 +     * current thread.  A writer thread has a hold on a lock for
  1.1290 +     * each lock action that is not matched by an unlock action.
  1.1291 +     *
  1.1292 +     * @return the number of holds on the write lock by the current thread,
  1.1293 +     *         or zero if the write lock is not held by the current thread
  1.1294 +     */
  1.1295 +    public int getWriteHoldCount() {
  1.1296 +        return sync.getWriteHoldCount();
  1.1297 +    }
  1.1298 +
  1.1299 +    /**
  1.1300 +     * Queries the number of reentrant read holds on this lock by the
  1.1301 +     * current thread.  A reader thread has a hold on a lock for
  1.1302 +     * each lock action that is not matched by an unlock action.
  1.1303 +     *
  1.1304 +     * @return the number of holds on the read lock by the current thread,
  1.1305 +     *         or zero if the read lock is not held by the current thread
  1.1306 +     * @since 1.6
  1.1307 +     */
  1.1308 +    public int getReadHoldCount() {
  1.1309 +        return sync.getReadHoldCount();
  1.1310 +    }
  1.1311 +
  1.1312 +    /**
  1.1313 +     * Returns a collection containing threads that may be waiting to
  1.1314 +     * acquire the write lock.  Because the actual set of threads may
  1.1315 +     * change dynamically while constructing this result, the returned
  1.1316 +     * collection is only a best-effort estimate.  The elements of the
  1.1317 +     * returned collection are in no particular order.  This method is
  1.1318 +     * designed to facilitate construction of subclasses that provide
  1.1319 +     * more extensive lock monitoring facilities.
  1.1320 +     *
  1.1321 +     * @return the collection of threads
  1.1322 +     */
  1.1323 +    protected Collection<Thread> getQueuedWriterThreads() {
  1.1324 +        return sync.getExclusiveQueuedThreads();
  1.1325 +    }
  1.1326 +
  1.1327 +    /**
  1.1328 +     * Returns a collection containing threads that may be waiting to
  1.1329 +     * acquire the read lock.  Because the actual set of threads may
  1.1330 +     * change dynamically while constructing this result, the returned
  1.1331 +     * collection is only a best-effort estimate.  The elements of the
  1.1332 +     * returned collection are in no particular order.  This method is
  1.1333 +     * designed to facilitate construction of subclasses that provide
  1.1334 +     * more extensive lock monitoring facilities.
  1.1335 +     *
  1.1336 +     * @return the collection of threads
  1.1337 +     */
  1.1338 +    protected Collection<Thread> getQueuedReaderThreads() {
  1.1339 +        return sync.getSharedQueuedThreads();
  1.1340 +    }
  1.1341 +
  1.1342 +    /**
  1.1343 +     * Queries whether any threads are waiting to acquire the read or
  1.1344 +     * write lock. Note that because cancellations may occur at any
  1.1345 +     * time, a {@code true} return does not guarantee that any other
  1.1346 +     * thread will ever acquire a lock.  This method is designed
  1.1347 +     * primarily for use in monitoring of the system state.
  1.1348 +     *
  1.1349 +     * @return {@code true} if there may be other threads waiting to
  1.1350 +     *         acquire the lock
  1.1351 +     */
  1.1352 +    public final boolean hasQueuedThreads() {
  1.1353 +        return sync.hasQueuedThreads();
  1.1354 +    }
  1.1355 +
  1.1356 +    /**
  1.1357 +     * Queries whether the given thread is waiting to acquire either
  1.1358 +     * the read or write lock. Note that because cancellations may
  1.1359 +     * occur at any time, a {@code true} return does not guarantee
  1.1360 +     * that this thread will ever acquire a lock.  This method is
  1.1361 +     * designed primarily for use in monitoring of the system state.
  1.1362 +     *
  1.1363 +     * @param thread the thread
  1.1364 +     * @return {@code true} if the given thread is queued waiting for this lock
  1.1365 +     * @throws NullPointerException if the thread is null
  1.1366 +     */
  1.1367 +    public final boolean hasQueuedThread(Thread thread) {
  1.1368 +        return sync.isQueued(thread);
  1.1369 +    }
  1.1370 +
  1.1371 +    /**
  1.1372 +     * Returns an estimate of the number of threads waiting to acquire
  1.1373 +     * either the read or write lock.  The value is only an estimate
  1.1374 +     * because the number of threads may change dynamically while this
  1.1375 +     * method traverses internal data structures.  This method is
  1.1376 +     * designed for use in monitoring of the system state, not for
  1.1377 +     * synchronization control.
  1.1378 +     *
  1.1379 +     * @return the estimated number of threads waiting for this lock
  1.1380 +     */
  1.1381 +    public final int getQueueLength() {
  1.1382 +        return sync.getQueueLength();
  1.1383 +    }
  1.1384 +
  1.1385 +    /**
  1.1386 +     * Returns a collection containing threads that may be waiting to
  1.1387 +     * acquire either the read or write lock.  Because the actual set
  1.1388 +     * of threads may change dynamically while constructing this
  1.1389 +     * result, the returned collection is only a best-effort estimate.
  1.1390 +     * The elements of the returned collection are in no particular
  1.1391 +     * order.  This method is designed to facilitate construction of
  1.1392 +     * subclasses that provide more extensive monitoring facilities.
  1.1393 +     *
  1.1394 +     * @return the collection of threads
  1.1395 +     */
  1.1396 +    protected Collection<Thread> getQueuedThreads() {
  1.1397 +        return sync.getQueuedThreads();
  1.1398 +    }
  1.1399 +
  1.1400 +    /**
  1.1401 +     * Queries whether any threads are waiting on the given condition
  1.1402 +     * associated with the write lock. Note that because timeouts and
  1.1403 +     * interrupts may occur at any time, a {@code true} return does
  1.1404 +     * not guarantee that a future {@code signal} will awaken any
  1.1405 +     * threads.  This method is designed primarily for use in
  1.1406 +     * monitoring of the system state.
  1.1407 +     *
  1.1408 +     * @param condition the condition
  1.1409 +     * @return {@code true} if there are any waiting threads
  1.1410 +     * @throws IllegalMonitorStateException if this lock is not held
  1.1411 +     * @throws IllegalArgumentException if the given condition is
  1.1412 +     *         not associated with this lock
  1.1413 +     * @throws NullPointerException if the condition is null
  1.1414 +     */
  1.1415 +    public boolean hasWaiters(Condition condition) {
  1.1416 +        if (condition == null)
  1.1417 +            throw new NullPointerException();
  1.1418 +        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
  1.1419 +            throw new IllegalArgumentException("not owner");
  1.1420 +        return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
  1.1421 +    }
  1.1422 +
  1.1423 +    /**
  1.1424 +     * Returns an estimate of the number of threads waiting on the
  1.1425 +     * given condition associated with the write lock. Note that because
  1.1426 +     * timeouts and interrupts may occur at any time, the estimate
  1.1427 +     * serves only as an upper bound on the actual number of waiters.
  1.1428 +     * This method is designed for use in monitoring of the system
  1.1429 +     * state, not for synchronization control.
  1.1430 +     *
  1.1431 +     * @param condition the condition
  1.1432 +     * @return the estimated number of waiting threads
  1.1433 +     * @throws IllegalMonitorStateException if this lock is not held
  1.1434 +     * @throws IllegalArgumentException if the given condition is
  1.1435 +     *         not associated with this lock
  1.1436 +     * @throws NullPointerException if the condition is null
  1.1437 +     */
  1.1438 +    public int getWaitQueueLength(Condition condition) {
  1.1439 +        if (condition == null)
  1.1440 +            throw new NullPointerException();
  1.1441 +        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
  1.1442 +            throw new IllegalArgumentException("not owner");
  1.1443 +        return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
  1.1444 +    }
  1.1445 +
  1.1446 +    /**
  1.1447 +     * Returns a collection containing those threads that may be
  1.1448 +     * waiting on the given condition associated with the write lock.
  1.1449 +     * Because the actual set of threads may change dynamically while
  1.1450 +     * constructing this result, the returned collection is only a
  1.1451 +     * best-effort estimate. The elements of the returned collection
  1.1452 +     * are in no particular order.  This method is designed to
  1.1453 +     * facilitate construction of subclasses that provide more
  1.1454 +     * extensive condition monitoring facilities.
  1.1455 +     *
  1.1456 +     * @param condition the condition
  1.1457 +     * @return the collection of threads
  1.1458 +     * @throws IllegalMonitorStateException if this lock is not held
  1.1459 +     * @throws IllegalArgumentException if the given condition is
  1.1460 +     *         not associated with this lock
  1.1461 +     * @throws NullPointerException if the condition is null
  1.1462 +     */
  1.1463 +    protected Collection<Thread> getWaitingThreads(Condition condition) {
  1.1464 +        if (condition == null)
  1.1465 +            throw new NullPointerException();
  1.1466 +        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
  1.1467 +            throw new IllegalArgumentException("not owner");
  1.1468 +        return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
  1.1469 +    }
  1.1470 +
  1.1471 +    /**
  1.1472 +     * Returns a string identifying this lock, as well as its lock state.
  1.1473 +     * The state, in brackets, includes the String {@code "Write locks ="}
  1.1474 +     * followed by the number of reentrantly held write locks, and the
  1.1475 +     * String {@code "Read locks ="} followed by the number of held
  1.1476 +     * read locks.
  1.1477 +     *
  1.1478 +     * @return a string identifying this lock, as well as its lock state
  1.1479 +     */
  1.1480 +    public String toString() {
  1.1481 +        int c = sync.getCount();
  1.1482 +        int w = Sync.exclusiveCount(c);
  1.1483 +        int r = Sync.sharedCount(c);
  1.1484 +
  1.1485 +        return super.toString() +
  1.1486 +            "[Write locks = " + w + ", Read locks = " + r + "]";
  1.1487 +    }
  1.1488 +
  1.1489 +}