rt/emul/compact/src/main/java/java/util/concurrent/locks/ReentrantReadWriteLock.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 19 Mar 2016 10:46:31 +0100
branchjdk7-b147
changeset 1890 212417b74b72
permissions -rw-r--r--
Bringing in all concurrent package from JDK7-b147
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  *
     4  * This code is free software; you can redistribute it and/or modify it
     5  * under the terms of the GNU General Public License version 2 only, as
     6  * published by the Free Software Foundation.  Oracle designates this
     7  * particular file as subject to the "Classpath" exception as provided
     8  * by Oracle in the LICENSE file that accompanied this code.
     9  *
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    13  * version 2 for more details (a copy is included in the LICENSE file that
    14  * accompanied this code).
    15  *
    16  * You should have received a copy of the GNU General Public License version
    17  * 2 along with this work; if not, write to the Free Software Foundation,
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    19  *
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * or visit www.oracle.com if you need additional information or have any
    22  * questions.
    23  */
    24 
    25 /*
    26  * This file is available under and governed by the GNU General Public
    27  * License version 2 only, as published by the Free Software Foundation.
    28  * However, the following notice accompanied the original version of this
    29  * file:
    30  *
    31  * Written by Doug Lea with assistance from members of JCP JSR-166
    32  * Expert Group and released to the public domain, as explained at
    33  * http://creativecommons.org/publicdomain/zero/1.0/
    34  */
    35 
    36 package java.util.concurrent.locks;
    37 import java.util.concurrent.*;
    38 import java.util.concurrent.atomic.*;
    39 import java.util.*;
    40 
    41 /**
    42  * An implementation of {@link ReadWriteLock} supporting similar
    43  * semantics to {@link ReentrantLock}.
    44  * <p>This class has the following properties:
    45  *
    46  * <ul>
    47  * <li><b>Acquisition order</b>
    48  *
    49  * <p> This class does not impose a reader or writer preference
    50  * ordering for lock access.  However, it does support an optional
    51  * <em>fairness</em> policy.
    52  *
    53  * <dl>
    54  * <dt><b><i>Non-fair mode (default)</i></b>
    55  * <dd>When constructed as non-fair (the default), the order of entry
    56  * to the read and write lock is unspecified, subject to reentrancy
    57  * constraints.  A nonfair lock that is continuously contended may
    58  * indefinitely postpone one or more reader or writer threads, but
    59  * will normally have higher throughput than a fair lock.
    60  * <p>
    61  *
    62  * <dt><b><i>Fair mode</i></b>
    63  * <dd> When constructed as fair, threads contend for entry using an
    64  * approximately arrival-order policy. When the currently held lock
    65  * is released either the longest-waiting single writer thread will
    66  * be assigned the write lock, or if there is a group of reader threads
    67  * waiting longer than all waiting writer threads, that group will be
    68  * assigned the read lock.
    69  *
    70  * <p>A thread that tries to acquire a fair read lock (non-reentrantly)
    71  * will block if either the write lock is held, or there is a waiting
    72  * writer thread. The thread will not acquire the read lock until
    73  * after the oldest currently waiting writer thread has acquired and
    74  * released the write lock. Of course, if a waiting writer abandons
    75  * its wait, leaving one or more reader threads as the longest waiters
    76  * in the queue with the write lock free, then those readers will be
    77  * assigned the read lock.
    78  *
    79  * <p>A thread that tries to acquire a fair write lock (non-reentrantly)
    80  * will block unless both the read lock and write lock are free (which
    81  * implies there are no waiting threads).  (Note that the non-blocking
    82  * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
    83  * do not honor this fair setting and will acquire the lock if it is
    84  * possible, regardless of waiting threads.)
    85  * <p>
    86  * </dl>
    87  *
    88  * <li><b>Reentrancy</b>
    89  *
    90  * <p>This lock allows both readers and writers to reacquire read or
    91  * write locks in the style of a {@link ReentrantLock}. Non-reentrant
    92  * readers are not allowed until all write locks held by the writing
    93  * thread have been released.
    94  *
    95  * <p>Additionally, a writer can acquire the read lock, but not
    96  * vice-versa.  Among other applications, reentrancy can be useful
    97  * when write locks are held during calls or callbacks to methods that
    98  * perform reads under read locks.  If a reader tries to acquire the
    99  * write lock it will never succeed.
   100  *
   101  * <li><b>Lock downgrading</b>
   102  * <p>Reentrancy also allows downgrading from the write lock to a read lock,
   103  * by acquiring the write lock, then the read lock and then releasing the
   104  * write lock. However, upgrading from a read lock to the write lock is
   105  * <b>not</b> possible.
   106  *
   107  * <li><b>Interruption of lock acquisition</b>
   108  * <p>The read lock and write lock both support interruption during lock
   109  * acquisition.
   110  *
   111  * <li><b>{@link Condition} support</b>
   112  * <p>The write lock provides a {@link Condition} implementation that
   113  * behaves in the same way, with respect to the write lock, as the
   114  * {@link Condition} implementation provided by
   115  * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
   116  * This {@link Condition} can, of course, only be used with the write lock.
   117  *
   118  * <p>The read lock does not support a {@link Condition} and
   119  * {@code readLock().newCondition()} throws
   120  * {@code UnsupportedOperationException}.
   121  *
   122  * <li><b>Instrumentation</b>
   123  * <p>This class supports methods to determine whether locks
   124  * are held or contended. These methods are designed for monitoring
   125  * system state, not for synchronization control.
   126  * </ul>
   127  *
   128  * <p>Serialization of this class behaves in the same way as built-in
   129  * locks: a deserialized lock is in the unlocked state, regardless of
   130  * its state when serialized.
   131  *
   132  * <p><b>Sample usages</b>. Here is a code sketch showing how to perform
   133  * lock downgrading after updating a cache (exception handling is
   134  * particularly tricky when handling multiple locks in a non-nested
   135  * fashion):
   136  *
   137  * <pre> {@code
   138  * class CachedData {
   139  *   Object data;
   140  *   volatile boolean cacheValid;
   141  *   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
   142  *
   143  *   void processCachedData() {
   144  *     rwl.readLock().lock();
   145  *     if (!cacheValid) {
   146  *        // Must release read lock before acquiring write lock
   147  *        rwl.readLock().unlock();
   148  *        rwl.writeLock().lock();
   149  *        try {
   150  *          // Recheck state because another thread might have
   151  *          // acquired write lock and changed state before we did.
   152  *          if (!cacheValid) {
   153  *            data = ...
   154  *            cacheValid = true;
   155  *          }
   156  *          // Downgrade by acquiring read lock before releasing write lock
   157  *          rwl.readLock().lock();
   158  *        } finally {
   159  *          rwl.writeLock().unlock(); // Unlock write, still hold read
   160  *        }
   161  *     }
   162  *
   163  *     try {
   164  *       use(data);
   165  *     } finally {
   166  *       rwl.readLock().unlock();
   167  *     }
   168  *   }
   169  * }}</pre>
   170  *
   171  * ReentrantReadWriteLocks can be used to improve concurrency in some
   172  * uses of some kinds of Collections. This is typically worthwhile
   173  * only when the collections are expected to be large, accessed by
   174  * more reader threads than writer threads, and entail operations with
   175  * overhead that outweighs synchronization overhead. For example, here
   176  * is a class using a TreeMap that is expected to be large and
   177  * concurrently accessed.
   178  *
   179  * <pre>{@code
   180  * class RWDictionary {
   181  *    private final Map<String, Data> m = new TreeMap<String, Data>();
   182  *    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
   183  *    private final Lock r = rwl.readLock();
   184  *    private final Lock w = rwl.writeLock();
   185  *
   186  *    public Data get(String key) {
   187  *        r.lock();
   188  *        try { return m.get(key); }
   189  *        finally { r.unlock(); }
   190  *    }
   191  *    public String[] allKeys() {
   192  *        r.lock();
   193  *        try { return m.keySet().toArray(); }
   194  *        finally { r.unlock(); }
   195  *    }
   196  *    public Data put(String key, Data value) {
   197  *        w.lock();
   198  *        try { return m.put(key, value); }
   199  *        finally { w.unlock(); }
   200  *    }
   201  *    public void clear() {
   202  *        w.lock();
   203  *        try { m.clear(); }
   204  *        finally { w.unlock(); }
   205  *    }
   206  * }}</pre>
   207  *
   208  * <h3>Implementation Notes</h3>
   209  *
   210  * <p>This lock supports a maximum of 65535 recursive write locks
   211  * and 65535 read locks. Attempts to exceed these limits result in
   212  * {@link Error} throws from locking methods.
   213  *
   214  * @since 1.5
   215  * @author Doug Lea
   216  *
   217  */
   218 public class ReentrantReadWriteLock
   219         implements ReadWriteLock, java.io.Serializable {
   220     private static final long serialVersionUID = -6992448646407690164L;
   221     /** Inner class providing readlock */
   222     private final ReentrantReadWriteLock.ReadLock readerLock;
   223     /** Inner class providing writelock */
   224     private final ReentrantReadWriteLock.WriteLock writerLock;
   225     /** Performs all synchronization mechanics */
   226     final Sync sync;
   227 
   228     /**
   229      * Creates a new {@code ReentrantReadWriteLock} with
   230      * default (nonfair) ordering properties.
   231      */
   232     public ReentrantReadWriteLock() {
   233         this(false);
   234     }
   235 
   236     /**
   237      * Creates a new {@code ReentrantReadWriteLock} with
   238      * the given fairness policy.
   239      *
   240      * @param fair {@code true} if this lock should use a fair ordering policy
   241      */
   242     public ReentrantReadWriteLock(boolean fair) {
   243         sync = fair ? new FairSync() : new NonfairSync();
   244         readerLock = new ReadLock(this);
   245         writerLock = new WriteLock(this);
   246     }
   247 
   248     public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
   249     public ReentrantReadWriteLock.ReadLock  readLock()  { return readerLock; }
   250 
   251     /**
   252      * Synchronization implementation for ReentrantReadWriteLock.
   253      * Subclassed into fair and nonfair versions.
   254      */
   255     abstract static class Sync extends AbstractQueuedSynchronizer {
   256         private static final long serialVersionUID = 6317671515068378041L;
   257 
   258         /*
   259          * Read vs write count extraction constants and functions.
   260          * Lock state is logically divided into two unsigned shorts:
   261          * The lower one representing the exclusive (writer) lock hold count,
   262          * and the upper the shared (reader) hold count.
   263          */
   264 
   265         static final int SHARED_SHIFT   = 16;
   266         static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
   267         static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
   268         static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
   269 
   270         /** Returns the number of shared holds represented in count  */
   271         static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
   272         /** Returns the number of exclusive holds represented in count  */
   273         static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
   274 
   275         /**
   276          * A counter for per-thread read hold counts.
   277          * Maintained as a ThreadLocal; cached in cachedHoldCounter
   278          */
   279         static final class HoldCounter {
   280             int count = 0;
   281             // Use id, not reference, to avoid garbage retention
   282             final long tid = Thread.currentThread().getId();
   283         }
   284 
   285         /**
   286          * ThreadLocal subclass. Easiest to explicitly define for sake
   287          * of deserialization mechanics.
   288          */
   289         static final class ThreadLocalHoldCounter
   290             extends ThreadLocal<HoldCounter> {
   291             public HoldCounter initialValue() {
   292                 return new HoldCounter();
   293             }
   294         }
   295 
   296         /**
   297          * The number of reentrant read locks held by current thread.
   298          * Initialized only in constructor and readObject.
   299          * Removed whenever a thread's read hold count drops to 0.
   300          */
   301         private transient ThreadLocalHoldCounter readHolds;
   302 
   303         /**
   304          * The hold count of the last thread to successfully acquire
   305          * readLock. This saves ThreadLocal lookup in the common case
   306          * where the next thread to release is the last one to
   307          * acquire. This is non-volatile since it is just used
   308          * as a heuristic, and would be great for threads to cache.
   309          *
   310          * <p>Can outlive the Thread for which it is caching the read
   311          * hold count, but avoids garbage retention by not retaining a
   312          * reference to the Thread.
   313          *
   314          * <p>Accessed via a benign data race; relies on the memory
   315          * model's final field and out-of-thin-air guarantees.
   316          */
   317         private transient HoldCounter cachedHoldCounter;
   318 
   319         /**
   320          * firstReader is the first thread to have acquired the read lock.
   321          * firstReaderHoldCount is firstReader's hold count.
   322          *
   323          * <p>More precisely, firstReader is the unique thread that last
   324          * changed the shared count from 0 to 1, and has not released the
   325          * read lock since then; null if there is no such thread.
   326          *
   327          * <p>Cannot cause garbage retention unless the thread terminated
   328          * without relinquishing its read locks, since tryReleaseShared
   329          * sets it to null.
   330          *
   331          * <p>Accessed via a benign data race; relies on the memory
   332          * model's out-of-thin-air guarantees for references.
   333          *
   334          * <p>This allows tracking of read holds for uncontended read
   335          * locks to be very cheap.
   336          */
   337         private transient Thread firstReader = null;
   338         private transient int firstReaderHoldCount;
   339 
   340         Sync() {
   341             readHolds = new ThreadLocalHoldCounter();
   342             setState(getState()); // ensures visibility of readHolds
   343         }
   344 
   345         /*
   346          * Acquires and releases use the same code for fair and
   347          * nonfair locks, but differ in whether/how they allow barging
   348          * when queues are non-empty.
   349          */
   350 
   351         /**
   352          * Returns true if the current thread, when trying to acquire
   353          * the read lock, and otherwise eligible to do so, should block
   354          * because of policy for overtaking other waiting threads.
   355          */
   356         abstract boolean readerShouldBlock();
   357 
   358         /**
   359          * Returns true if the current thread, when trying to acquire
   360          * the write lock, and otherwise eligible to do so, should block
   361          * because of policy for overtaking other waiting threads.
   362          */
   363         abstract boolean writerShouldBlock();
   364 
   365         /*
   366          * Note that tryRelease and tryAcquire can be called by
   367          * Conditions. So it is possible that their arguments contain
   368          * both read and write holds that are all released during a
   369          * condition wait and re-established in tryAcquire.
   370          */
   371 
   372         protected final boolean tryRelease(int releases) {
   373             if (!isHeldExclusively())
   374                 throw new IllegalMonitorStateException();
   375             int nextc = getState() - releases;
   376             boolean free = exclusiveCount(nextc) == 0;
   377             if (free)
   378                 setExclusiveOwnerThread(null);
   379             setState(nextc);
   380             return free;
   381         }
   382 
   383         protected final boolean tryAcquire(int acquires) {
   384             /*
   385              * Walkthrough:
   386              * 1. If read count nonzero or write count nonzero
   387              *    and owner is a different thread, fail.
   388              * 2. If count would saturate, fail. (This can only
   389              *    happen if count is already nonzero.)
   390              * 3. Otherwise, this thread is eligible for lock if
   391              *    it is either a reentrant acquire or
   392              *    queue policy allows it. If so, update state
   393              *    and set owner.
   394              */
   395             Thread current = Thread.currentThread();
   396             int c = getState();
   397             int w = exclusiveCount(c);
   398             if (c != 0) {
   399                 // (Note: if c != 0 and w == 0 then shared count != 0)
   400                 if (w == 0 || current != getExclusiveOwnerThread())
   401                     return false;
   402                 if (w + exclusiveCount(acquires) > MAX_COUNT)
   403                     throw new Error("Maximum lock count exceeded");
   404                 // Reentrant acquire
   405                 setState(c + acquires);
   406                 return true;
   407             }
   408             if (writerShouldBlock() ||
   409                 !compareAndSetState(c, c + acquires))
   410                 return false;
   411             setExclusiveOwnerThread(current);
   412             return true;
   413         }
   414 
   415         protected final boolean tryReleaseShared(int unused) {
   416             Thread current = Thread.currentThread();
   417             if (firstReader == current) {
   418                 // assert firstReaderHoldCount > 0;
   419                 if (firstReaderHoldCount == 1)
   420                     firstReader = null;
   421                 else
   422                     firstReaderHoldCount--;
   423             } else {
   424                 HoldCounter rh = cachedHoldCounter;
   425                 if (rh == null || rh.tid != current.getId())
   426                     rh = readHolds.get();
   427                 int count = rh.count;
   428                 if (count <= 1) {
   429                     readHolds.remove();
   430                     if (count <= 0)
   431                         throw unmatchedUnlockException();
   432                 }
   433                 --rh.count;
   434             }
   435             for (;;) {
   436                 int c = getState();
   437                 int nextc = c - SHARED_UNIT;
   438                 if (compareAndSetState(c, nextc))
   439                     // Releasing the read lock has no effect on readers,
   440                     // but it may allow waiting writers to proceed if
   441                     // both read and write locks are now free.
   442                     return nextc == 0;
   443             }
   444         }
   445 
   446         private IllegalMonitorStateException unmatchedUnlockException() {
   447             return new IllegalMonitorStateException(
   448                 "attempt to unlock read lock, not locked by current thread");
   449         }
   450 
   451         protected final int tryAcquireShared(int unused) {
   452             /*
   453              * Walkthrough:
   454              * 1. If write lock held by another thread, fail.
   455              * 2. Otherwise, this thread is eligible for
   456              *    lock wrt state, so ask if it should block
   457              *    because of queue policy. If not, try
   458              *    to grant by CASing state and updating count.
   459              *    Note that step does not check for reentrant
   460              *    acquires, which is postponed to full version
   461              *    to avoid having to check hold count in
   462              *    the more typical non-reentrant case.
   463              * 3. If step 2 fails either because thread
   464              *    apparently not eligible or CAS fails or count
   465              *    saturated, chain to version with full retry loop.
   466              */
   467             Thread current = Thread.currentThread();
   468             int c = getState();
   469             if (exclusiveCount(c) != 0 &&
   470                 getExclusiveOwnerThread() != current)
   471                 return -1;
   472             int r = sharedCount(c);
   473             if (!readerShouldBlock() &&
   474                 r < MAX_COUNT &&
   475                 compareAndSetState(c, c + SHARED_UNIT)) {
   476                 if (r == 0) {
   477                     firstReader = current;
   478                     firstReaderHoldCount = 1;
   479                 } else if (firstReader == current) {
   480                     firstReaderHoldCount++;
   481                 } else {
   482                     HoldCounter rh = cachedHoldCounter;
   483                     if (rh == null || rh.tid != current.getId())
   484                         cachedHoldCounter = rh = readHolds.get();
   485                     else if (rh.count == 0)
   486                         readHolds.set(rh);
   487                     rh.count++;
   488                 }
   489                 return 1;
   490             }
   491             return fullTryAcquireShared(current);
   492         }
   493 
   494         /**
   495          * Full version of acquire for reads, that handles CAS misses
   496          * and reentrant reads not dealt with in tryAcquireShared.
   497          */
   498         final int fullTryAcquireShared(Thread current) {
   499             /*
   500              * This code is in part redundant with that in
   501              * tryAcquireShared but is simpler overall by not
   502              * complicating tryAcquireShared with interactions between
   503              * retries and lazily reading hold counts.
   504              */
   505             HoldCounter rh = null;
   506             for (;;) {
   507                 int c = getState();
   508                 if (exclusiveCount(c) != 0) {
   509                     if (getExclusiveOwnerThread() != current)
   510                         return -1;
   511                     // else we hold the exclusive lock; blocking here
   512                     // would cause deadlock.
   513                 } else if (readerShouldBlock()) {
   514                     // Make sure we're not acquiring read lock reentrantly
   515                     if (firstReader == current) {
   516                         // assert firstReaderHoldCount > 0;
   517                     } else {
   518                         if (rh == null) {
   519                             rh = cachedHoldCounter;
   520                             if (rh == null || rh.tid != current.getId()) {
   521                                 rh = readHolds.get();
   522                                 if (rh.count == 0)
   523                                     readHolds.remove();
   524                             }
   525                         }
   526                         if (rh.count == 0)
   527                             return -1;
   528                     }
   529                 }
   530                 if (sharedCount(c) == MAX_COUNT)
   531                     throw new Error("Maximum lock count exceeded");
   532                 if (compareAndSetState(c, c + SHARED_UNIT)) {
   533                     if (sharedCount(c) == 0) {
   534                         firstReader = current;
   535                         firstReaderHoldCount = 1;
   536                     } else if (firstReader == current) {
   537                         firstReaderHoldCount++;
   538                     } else {
   539                         if (rh == null)
   540                             rh = cachedHoldCounter;
   541                         if (rh == null || rh.tid != current.getId())
   542                             rh = readHolds.get();
   543                         else if (rh.count == 0)
   544                             readHolds.set(rh);
   545                         rh.count++;
   546                         cachedHoldCounter = rh; // cache for release
   547                     }
   548                     return 1;
   549                 }
   550             }
   551         }
   552 
   553         /**
   554          * Performs tryLock for write, enabling barging in both modes.
   555          * This is identical in effect to tryAcquire except for lack
   556          * of calls to writerShouldBlock.
   557          */
   558         final boolean tryWriteLock() {
   559             Thread current = Thread.currentThread();
   560             int c = getState();
   561             if (c != 0) {
   562                 int w = exclusiveCount(c);
   563                 if (w == 0 || current != getExclusiveOwnerThread())
   564                     return false;
   565                 if (w == MAX_COUNT)
   566                     throw new Error("Maximum lock count exceeded");
   567             }
   568             if (!compareAndSetState(c, c + 1))
   569                 return false;
   570             setExclusiveOwnerThread(current);
   571             return true;
   572         }
   573 
   574         /**
   575          * Performs tryLock for read, enabling barging in both modes.
   576          * This is identical in effect to tryAcquireShared except for
   577          * lack of calls to readerShouldBlock.
   578          */
   579         final boolean tryReadLock() {
   580             Thread current = Thread.currentThread();
   581             for (;;) {
   582                 int c = getState();
   583                 if (exclusiveCount(c) != 0 &&
   584                     getExclusiveOwnerThread() != current)
   585                     return false;
   586                 int r = sharedCount(c);
   587                 if (r == MAX_COUNT)
   588                     throw new Error("Maximum lock count exceeded");
   589                 if (compareAndSetState(c, c + SHARED_UNIT)) {
   590                     if (r == 0) {
   591                         firstReader = current;
   592                         firstReaderHoldCount = 1;
   593                     } else if (firstReader == current) {
   594                         firstReaderHoldCount++;
   595                     } else {
   596                         HoldCounter rh = cachedHoldCounter;
   597                         if (rh == null || rh.tid != current.getId())
   598                             cachedHoldCounter = rh = readHolds.get();
   599                         else if (rh.count == 0)
   600                             readHolds.set(rh);
   601                         rh.count++;
   602                     }
   603                     return true;
   604                 }
   605             }
   606         }
   607 
   608         protected final boolean isHeldExclusively() {
   609             // While we must in general read state before owner,
   610             // we don't need to do so to check if current thread is owner
   611             return getExclusiveOwnerThread() == Thread.currentThread();
   612         }
   613 
   614         // Methods relayed to outer class
   615 
   616         final ConditionObject newCondition() {
   617             return new ConditionObject();
   618         }
   619 
   620         final Thread getOwner() {
   621             // Must read state before owner to ensure memory consistency
   622             return ((exclusiveCount(getState()) == 0) ?
   623                     null :
   624                     getExclusiveOwnerThread());
   625         }
   626 
   627         final int getReadLockCount() {
   628             return sharedCount(getState());
   629         }
   630 
   631         final boolean isWriteLocked() {
   632             return exclusiveCount(getState()) != 0;
   633         }
   634 
   635         final int getWriteHoldCount() {
   636             return isHeldExclusively() ? exclusiveCount(getState()) : 0;
   637         }
   638 
   639         final int getReadHoldCount() {
   640             if (getReadLockCount() == 0)
   641                 return 0;
   642 
   643             Thread current = Thread.currentThread();
   644             if (firstReader == current)
   645                 return firstReaderHoldCount;
   646 
   647             HoldCounter rh = cachedHoldCounter;
   648             if (rh != null && rh.tid == current.getId())
   649                 return rh.count;
   650 
   651             int count = readHolds.get().count;
   652             if (count == 0) readHolds.remove();
   653             return count;
   654         }
   655 
   656         /**
   657          * Reconstitute this lock instance from a stream
   658          * @param s the stream
   659          */
   660         private void readObject(java.io.ObjectInputStream s)
   661             throws java.io.IOException, ClassNotFoundException {
   662             s.defaultReadObject();
   663             readHolds = new ThreadLocalHoldCounter();
   664             setState(0); // reset to unlocked state
   665         }
   666 
   667         final int getCount() { return getState(); }
   668     }
   669 
   670     /**
   671      * Nonfair version of Sync
   672      */
   673     static final class NonfairSync extends Sync {
   674         private static final long serialVersionUID = -8159625535654395037L;
   675         final boolean writerShouldBlock() {
   676             return false; // writers can always barge
   677         }
   678         final boolean readerShouldBlock() {
   679             /* As a heuristic to avoid indefinite writer starvation,
   680              * block if the thread that momentarily appears to be head
   681              * of queue, if one exists, is a waiting writer.  This is
   682              * only a probabilistic effect since a new reader will not
   683              * block if there is a waiting writer behind other enabled
   684              * readers that have not yet drained from the queue.
   685              */
   686             return apparentlyFirstQueuedIsExclusive();
   687         }
   688     }
   689 
   690     /**
   691      * Fair version of Sync
   692      */
   693     static final class FairSync extends Sync {
   694         private static final long serialVersionUID = -2274990926593161451L;
   695         final boolean writerShouldBlock() {
   696             return hasQueuedPredecessors();
   697         }
   698         final boolean readerShouldBlock() {
   699             return hasQueuedPredecessors();
   700         }
   701     }
   702 
   703     /**
   704      * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
   705      */
   706     public static class ReadLock implements Lock, java.io.Serializable {
   707         private static final long serialVersionUID = -5992448646407690164L;
   708         private final Sync sync;
   709 
   710         /**
   711          * Constructor for use by subclasses
   712          *
   713          * @param lock the outer lock object
   714          * @throws NullPointerException if the lock is null
   715          */
   716         protected ReadLock(ReentrantReadWriteLock lock) {
   717             sync = lock.sync;
   718         }
   719 
   720         /**
   721          * Acquires the read lock.
   722          *
   723          * <p>Acquires the read lock if the write lock is not held by
   724          * another thread and returns immediately.
   725          *
   726          * <p>If the write lock is held by another thread then
   727          * the current thread becomes disabled for thread scheduling
   728          * purposes and lies dormant until the read lock has been acquired.
   729          */
   730         public void lock() {
   731             sync.acquireShared(1);
   732         }
   733 
   734         /**
   735          * Acquires the read lock unless the current thread is
   736          * {@linkplain Thread#interrupt interrupted}.
   737          *
   738          * <p>Acquires the read lock if the write lock is not held
   739          * by another thread and returns immediately.
   740          *
   741          * <p>If the write lock is held by another thread then the
   742          * current thread becomes disabled for thread scheduling
   743          * purposes and lies dormant until one of two things happens:
   744          *
   745          * <ul>
   746          *
   747          * <li>The read lock is acquired by the current thread; or
   748          *
   749          * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   750          * the current thread.
   751          *
   752          * </ul>
   753          *
   754          * <p>If the current thread:
   755          *
   756          * <ul>
   757          *
   758          * <li>has its interrupted status set on entry to this method; or
   759          *
   760          * <li>is {@linkplain Thread#interrupt interrupted} while
   761          * acquiring the read lock,
   762          *
   763          * </ul>
   764          *
   765          * then {@link InterruptedException} is thrown and the current
   766          * thread's interrupted status is cleared.
   767          *
   768          * <p>In this implementation, as this method is an explicit
   769          * interruption point, preference is given to responding to
   770          * the interrupt over normal or reentrant acquisition of the
   771          * lock.
   772          *
   773          * @throws InterruptedException if the current thread is interrupted
   774          */
   775         public void lockInterruptibly() throws InterruptedException {
   776             sync.acquireSharedInterruptibly(1);
   777         }
   778 
   779         /**
   780          * Acquires the read lock only if the write lock is not held by
   781          * another thread at the time of invocation.
   782          *
   783          * <p>Acquires the read lock if the write lock is not held by
   784          * another thread and returns immediately with the value
   785          * {@code true}. Even when this lock has been set to use a
   786          * fair ordering policy, a call to {@code tryLock()}
   787          * <em>will</em> immediately acquire the read lock if it is
   788          * available, whether or not other threads are currently
   789          * waiting for the read lock.  This &quot;barging&quot; behavior
   790          * can be useful in certain circumstances, even though it
   791          * breaks fairness. If you want to honor the fairness setting
   792          * for this lock, then use {@link #tryLock(long, TimeUnit)
   793          * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
   794          * (it also detects interruption).
   795          *
   796          * <p>If the write lock is held by another thread then
   797          * this method will return immediately with the value
   798          * {@code false}.
   799          *
   800          * @return {@code true} if the read lock was acquired
   801          */
   802         public  boolean tryLock() {
   803             return sync.tryReadLock();
   804         }
   805 
   806         /**
   807          * Acquires the read lock if the write lock is not held by
   808          * another thread within the given waiting time and the
   809          * current thread has not been {@linkplain Thread#interrupt
   810          * interrupted}.
   811          *
   812          * <p>Acquires the read lock if the write lock is not held by
   813          * another thread and returns immediately with the value
   814          * {@code true}. If this lock has been set to use a fair
   815          * ordering policy then an available lock <em>will not</em> be
   816          * acquired if any other threads are waiting for the
   817          * lock. This is in contrast to the {@link #tryLock()}
   818          * method. If you want a timed {@code tryLock} that does
   819          * permit barging on a fair lock then combine the timed and
   820          * un-timed forms together:
   821          *
   822          * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
   823          * </pre>
   824          *
   825          * <p>If the write lock is held by another thread then the
   826          * current thread becomes disabled for thread scheduling
   827          * purposes and lies dormant until one of three things happens:
   828          *
   829          * <ul>
   830          *
   831          * <li>The read lock is acquired by the current thread; or
   832          *
   833          * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   834          * the current thread; or
   835          *
   836          * <li>The specified waiting time elapses.
   837          *
   838          * </ul>
   839          *
   840          * <p>If the read lock is acquired then the value {@code true} is
   841          * returned.
   842          *
   843          * <p>If the current thread:
   844          *
   845          * <ul>
   846          *
   847          * <li>has its interrupted status set on entry to this method; or
   848          *
   849          * <li>is {@linkplain Thread#interrupt interrupted} while
   850          * acquiring the read lock,
   851          *
   852          * </ul> then {@link InterruptedException} is thrown and the
   853          * current thread's interrupted status is cleared.
   854          *
   855          * <p>If the specified waiting time elapses then the value
   856          * {@code false} is returned.  If the time is less than or
   857          * equal to zero, the method will not wait at all.
   858          *
   859          * <p>In this implementation, as this method is an explicit
   860          * interruption point, preference is given to responding to
   861          * the interrupt over normal or reentrant acquisition of the
   862          * lock, and over reporting the elapse of the waiting time.
   863          *
   864          * @param timeout the time to wait for the read lock
   865          * @param unit the time unit of the timeout argument
   866          * @return {@code true} if the read lock was acquired
   867          * @throws InterruptedException if the current thread is interrupted
   868          * @throws NullPointerException if the time unit is null
   869          *
   870          */
   871         public boolean tryLock(long timeout, TimeUnit unit)
   872                 throws InterruptedException {
   873             return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
   874         }
   875 
   876         /**
   877          * Attempts to release this lock.
   878          *
   879          * <p> If the number of readers is now zero then the lock
   880          * is made available for write lock attempts.
   881          */
   882         public  void unlock() {
   883             sync.releaseShared(1);
   884         }
   885 
   886         /**
   887          * Throws {@code UnsupportedOperationException} because
   888          * {@code ReadLocks} do not support conditions.
   889          *
   890          * @throws UnsupportedOperationException always
   891          */
   892         public Condition newCondition() {
   893             throw new UnsupportedOperationException();
   894         }
   895 
   896         /**
   897          * Returns a string identifying this lock, as well as its lock state.
   898          * The state, in brackets, includes the String {@code "Read locks ="}
   899          * followed by the number of held read locks.
   900          *
   901          * @return a string identifying this lock, as well as its lock state
   902          */
   903         public String toString() {
   904             int r = sync.getReadLockCount();
   905             return super.toString() +
   906                 "[Read locks = " + r + "]";
   907         }
   908     }
   909 
   910     /**
   911      * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
   912      */
   913     public static class WriteLock implements Lock, java.io.Serializable {
   914         private static final long serialVersionUID = -4992448646407690164L;
   915         private final Sync sync;
   916 
   917         /**
   918          * Constructor for use by subclasses
   919          *
   920          * @param lock the outer lock object
   921          * @throws NullPointerException if the lock is null
   922          */
   923         protected WriteLock(ReentrantReadWriteLock lock) {
   924             sync = lock.sync;
   925         }
   926 
   927         /**
   928          * Acquires the write lock.
   929          *
   930          * <p>Acquires the write lock if neither the read nor write lock
   931          * are held by another thread
   932          * and returns immediately, setting the write lock hold count to
   933          * one.
   934          *
   935          * <p>If the current thread already holds the write lock then the
   936          * hold count is incremented by one and the method returns
   937          * immediately.
   938          *
   939          * <p>If the lock is held by another thread then the current
   940          * thread becomes disabled for thread scheduling purposes and
   941          * lies dormant until the write lock has been acquired, at which
   942          * time the write lock hold count is set to one.
   943          */
   944         public void lock() {
   945             sync.acquire(1);
   946         }
   947 
   948         /**
   949          * Acquires the write lock unless the current thread is
   950          * {@linkplain Thread#interrupt interrupted}.
   951          *
   952          * <p>Acquires the write lock if neither the read nor write lock
   953          * are held by another thread
   954          * and returns immediately, setting the write lock hold count to
   955          * one.
   956          *
   957          * <p>If the current thread already holds this lock then the
   958          * hold count is incremented by one and the method returns
   959          * immediately.
   960          *
   961          * <p>If the lock is held by another thread then the current
   962          * thread becomes disabled for thread scheduling purposes and
   963          * lies dormant until one of two things happens:
   964          *
   965          * <ul>
   966          *
   967          * <li>The write lock is acquired by the current thread; or
   968          *
   969          * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   970          * the current thread.
   971          *
   972          * </ul>
   973          *
   974          * <p>If the write lock is acquired by the current thread then the
   975          * lock hold count is set to one.
   976          *
   977          * <p>If the current thread:
   978          *
   979          * <ul>
   980          *
   981          * <li>has its interrupted status set on entry to this method;
   982          * or
   983          *
   984          * <li>is {@linkplain Thread#interrupt interrupted} while
   985          * acquiring the write lock,
   986          *
   987          * </ul>
   988          *
   989          * then {@link InterruptedException} is thrown and the current
   990          * thread's interrupted status is cleared.
   991          *
   992          * <p>In this implementation, as this method is an explicit
   993          * interruption point, preference is given to responding to
   994          * the interrupt over normal or reentrant acquisition of the
   995          * lock.
   996          *
   997          * @throws InterruptedException if the current thread is interrupted
   998          */
   999         public void lockInterruptibly() throws InterruptedException {
  1000             sync.acquireInterruptibly(1);
  1001         }
  1002 
  1003         /**
  1004          * Acquires the write lock only if it is not held by another thread
  1005          * at the time of invocation.
  1006          *
  1007          * <p>Acquires the write lock if neither the read nor write lock
  1008          * are held by another thread
  1009          * and returns immediately with the value {@code true},
  1010          * setting the write lock hold count to one. Even when this lock has
  1011          * been set to use a fair ordering policy, a call to
  1012          * {@code tryLock()} <em>will</em> immediately acquire the
  1013          * lock if it is available, whether or not other threads are
  1014          * currently waiting for the write lock.  This &quot;barging&quot;
  1015          * behavior can be useful in certain circumstances, even
  1016          * though it breaks fairness. If you want to honor the
  1017          * fairness setting for this lock, then use {@link
  1018          * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
  1019          * which is almost equivalent (it also detects interruption).
  1020          *
  1021          * <p> If the current thread already holds this lock then the
  1022          * hold count is incremented by one and the method returns
  1023          * {@code true}.
  1024          *
  1025          * <p>If the lock is held by another thread then this method
  1026          * will return immediately with the value {@code false}.
  1027          *
  1028          * @return {@code true} if the lock was free and was acquired
  1029          * by the current thread, or the write lock was already held
  1030          * by the current thread; and {@code false} otherwise.
  1031          */
  1032         public boolean tryLock( ) {
  1033             return sync.tryWriteLock();
  1034         }
  1035 
  1036         /**
  1037          * Acquires the write lock if it is not held by another thread
  1038          * within the given waiting time and the current thread has
  1039          * not been {@linkplain Thread#interrupt interrupted}.
  1040          *
  1041          * <p>Acquires the write lock if neither the read nor write lock
  1042          * are held by another thread
  1043          * and returns immediately with the value {@code true},
  1044          * setting the write lock hold count to one. If this lock has been
  1045          * set to use a fair ordering policy then an available lock
  1046          * <em>will not</em> be acquired if any other threads are
  1047          * waiting for the write lock. This is in contrast to the {@link
  1048          * #tryLock()} method. If you want a timed {@code tryLock}
  1049          * that does permit barging on a fair lock then combine the
  1050          * timed and un-timed forms together:
  1051          *
  1052          * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
  1053          * </pre>
  1054          *
  1055          * <p>If the current thread already holds this lock then the
  1056          * hold count is incremented by one and the method returns
  1057          * {@code true}.
  1058          *
  1059          * <p>If the lock is held by another thread then the current
  1060          * thread becomes disabled for thread scheduling purposes and
  1061          * lies dormant until one of three things happens:
  1062          *
  1063          * <ul>
  1064          *
  1065          * <li>The write lock is acquired by the current thread; or
  1066          *
  1067          * <li>Some other thread {@linkplain Thread#interrupt interrupts}
  1068          * the current thread; or
  1069          *
  1070          * <li>The specified waiting time elapses
  1071          *
  1072          * </ul>
  1073          *
  1074          * <p>If the write lock is acquired then the value {@code true} is
  1075          * returned and the write lock hold count is set to one.
  1076          *
  1077          * <p>If the current thread:
  1078          *
  1079          * <ul>
  1080          *
  1081          * <li>has its interrupted status set on entry to this method;
  1082          * or
  1083          *
  1084          * <li>is {@linkplain Thread#interrupt interrupted} while
  1085          * acquiring the write lock,
  1086          *
  1087          * </ul>
  1088          *
  1089          * then {@link InterruptedException} is thrown and the current
  1090          * thread's interrupted status is cleared.
  1091          *
  1092          * <p>If the specified waiting time elapses then the value
  1093          * {@code false} is returned.  If the time is less than or
  1094          * equal to zero, the method will not wait at all.
  1095          *
  1096          * <p>In this implementation, as this method is an explicit
  1097          * interruption point, preference is given to responding to
  1098          * the interrupt over normal or reentrant acquisition of the
  1099          * lock, and over reporting the elapse of the waiting time.
  1100          *
  1101          * @param timeout the time to wait for the write lock
  1102          * @param unit the time unit of the timeout argument
  1103          *
  1104          * @return {@code true} if the lock was free and was acquired
  1105          * by the current thread, or the write lock was already held by the
  1106          * current thread; and {@code false} if the waiting time
  1107          * elapsed before the lock could be acquired.
  1108          *
  1109          * @throws InterruptedException if the current thread is interrupted
  1110          * @throws NullPointerException if the time unit is null
  1111          *
  1112          */
  1113         public boolean tryLock(long timeout, TimeUnit unit)
  1114                 throws InterruptedException {
  1115             return sync.tryAcquireNanos(1, unit.toNanos(timeout));
  1116         }
  1117 
  1118         /**
  1119          * Attempts to release this lock.
  1120          *
  1121          * <p>If the current thread is the holder of this lock then
  1122          * the hold count is decremented. If the hold count is now
  1123          * zero then the lock is released.  If the current thread is
  1124          * not the holder of this lock then {@link
  1125          * IllegalMonitorStateException} is thrown.
  1126          *
  1127          * @throws IllegalMonitorStateException if the current thread does not
  1128          * hold this lock.
  1129          */
  1130         public void unlock() {
  1131             sync.release(1);
  1132         }
  1133 
  1134         /**
  1135          * Returns a {@link Condition} instance for use with this
  1136          * {@link Lock} instance.
  1137          * <p>The returned {@link Condition} instance supports the same
  1138          * usages as do the {@link Object} monitor methods ({@link
  1139          * Object#wait() wait}, {@link Object#notify notify}, and {@link
  1140          * Object#notifyAll notifyAll}) when used with the built-in
  1141          * monitor lock.
  1142          *
  1143          * <ul>
  1144          *
  1145          * <li>If this write lock is not held when any {@link
  1146          * Condition} method is called then an {@link
  1147          * IllegalMonitorStateException} is thrown.  (Read locks are
  1148          * held independently of write locks, so are not checked or
  1149          * affected. However it is essentially always an error to
  1150          * invoke a condition waiting method when the current thread
  1151          * has also acquired read locks, since other threads that
  1152          * could unblock it will not be able to acquire the write
  1153          * lock.)
  1154          *
  1155          * <li>When the condition {@linkplain Condition#await() waiting}
  1156          * methods are called the write lock is released and, before
  1157          * they return, the write lock is reacquired and the lock hold
  1158          * count restored to what it was when the method was called.
  1159          *
  1160          * <li>If a thread is {@linkplain Thread#interrupt interrupted} while
  1161          * waiting then the wait will terminate, an {@link
  1162          * InterruptedException} will be thrown, and the thread's
  1163          * interrupted status will be cleared.
  1164          *
  1165          * <li> Waiting threads are signalled in FIFO order.
  1166          *
  1167          * <li>The ordering of lock reacquisition for threads returning
  1168          * from waiting methods is the same as for threads initially
  1169          * acquiring the lock, which is in the default case not specified,
  1170          * but for <em>fair</em> locks favors those threads that have been
  1171          * waiting the longest.
  1172          *
  1173          * </ul>
  1174          *
  1175          * @return the Condition object
  1176          */
  1177         public Condition newCondition() {
  1178             return sync.newCondition();
  1179         }
  1180 
  1181         /**
  1182          * Returns a string identifying this lock, as well as its lock
  1183          * state.  The state, in brackets includes either the String
  1184          * {@code "Unlocked"} or the String {@code "Locked by"}
  1185          * followed by the {@linkplain Thread#getName name} of the owning thread.
  1186          *
  1187          * @return a string identifying this lock, as well as its lock state
  1188          */
  1189         public String toString() {
  1190             Thread o = sync.getOwner();
  1191             return super.toString() + ((o == null) ?
  1192                                        "[Unlocked]" :
  1193                                        "[Locked by thread " + o.getName() + "]");
  1194         }
  1195 
  1196         /**
  1197          * Queries if this write lock is held by the current thread.
  1198          * Identical in effect to {@link
  1199          * ReentrantReadWriteLock#isWriteLockedByCurrentThread}.
  1200          *
  1201          * @return {@code true} if the current thread holds this lock and
  1202          *         {@code false} otherwise
  1203          * @since 1.6
  1204          */
  1205         public boolean isHeldByCurrentThread() {
  1206             return sync.isHeldExclusively();
  1207         }
  1208 
  1209         /**
  1210          * Queries the number of holds on this write lock by the current
  1211          * thread.  A thread has a hold on a lock for each lock action
  1212          * that is not matched by an unlock action.  Identical in effect
  1213          * to {@link ReentrantReadWriteLock#getWriteHoldCount}.
  1214          *
  1215          * @return the number of holds on this lock by the current thread,
  1216          *         or zero if this lock is not held by the current thread
  1217          * @since 1.6
  1218          */
  1219         public int getHoldCount() {
  1220             return sync.getWriteHoldCount();
  1221         }
  1222     }
  1223 
  1224     // Instrumentation and status
  1225 
  1226     /**
  1227      * Returns {@code true} if this lock has fairness set true.
  1228      *
  1229      * @return {@code true} if this lock has fairness set true
  1230      */
  1231     public final boolean isFair() {
  1232         return sync instanceof FairSync;
  1233     }
  1234 
  1235     /**
  1236      * Returns the thread that currently owns the write lock, or
  1237      * {@code null} if not owned. When this method is called by a
  1238      * thread that is not the owner, the return value reflects a
  1239      * best-effort approximation of current lock status. For example,
  1240      * the owner may be momentarily {@code null} even if there are
  1241      * threads trying to acquire the lock but have not yet done so.
  1242      * This method is designed to facilitate construction of
  1243      * subclasses that provide more extensive lock monitoring
  1244      * facilities.
  1245      *
  1246      * @return the owner, or {@code null} if not owned
  1247      */
  1248     protected Thread getOwner() {
  1249         return sync.getOwner();
  1250     }
  1251 
  1252     /**
  1253      * Queries the number of read locks held for this lock. This
  1254      * method is designed for use in monitoring system state, not for
  1255      * synchronization control.
  1256      * @return the number of read locks held.
  1257      */
  1258     public int getReadLockCount() {
  1259         return sync.getReadLockCount();
  1260     }
  1261 
  1262     /**
  1263      * Queries if the write lock is held by any thread. This method is
  1264      * designed for use in monitoring system state, not for
  1265      * synchronization control.
  1266      *
  1267      * @return {@code true} if any thread holds the write lock and
  1268      *         {@code false} otherwise
  1269      */
  1270     public boolean isWriteLocked() {
  1271         return sync.isWriteLocked();
  1272     }
  1273 
  1274     /**
  1275      * Queries if the write lock is held by the current thread.
  1276      *
  1277      * @return {@code true} if the current thread holds the write lock and
  1278      *         {@code false} otherwise
  1279      */
  1280     public boolean isWriteLockedByCurrentThread() {
  1281         return sync.isHeldExclusively();
  1282     }
  1283 
  1284     /**
  1285      * Queries the number of reentrant write holds on this lock by the
  1286      * current thread.  A writer thread has a hold on a lock for
  1287      * each lock action that is not matched by an unlock action.
  1288      *
  1289      * @return the number of holds on the write lock by the current thread,
  1290      *         or zero if the write lock is not held by the current thread
  1291      */
  1292     public int getWriteHoldCount() {
  1293         return sync.getWriteHoldCount();
  1294     }
  1295 
  1296     /**
  1297      * Queries the number of reentrant read holds on this lock by the
  1298      * current thread.  A reader thread has a hold on a lock for
  1299      * each lock action that is not matched by an unlock action.
  1300      *
  1301      * @return the number of holds on the read lock by the current thread,
  1302      *         or zero if the read lock is not held by the current thread
  1303      * @since 1.6
  1304      */
  1305     public int getReadHoldCount() {
  1306         return sync.getReadHoldCount();
  1307     }
  1308 
  1309     /**
  1310      * Returns a collection containing threads that may be waiting to
  1311      * acquire the write lock.  Because the actual set of threads may
  1312      * change dynamically while constructing this result, the returned
  1313      * collection is only a best-effort estimate.  The elements of the
  1314      * returned collection are in no particular order.  This method is
  1315      * designed to facilitate construction of subclasses that provide
  1316      * more extensive lock monitoring facilities.
  1317      *
  1318      * @return the collection of threads
  1319      */
  1320     protected Collection<Thread> getQueuedWriterThreads() {
  1321         return sync.getExclusiveQueuedThreads();
  1322     }
  1323 
  1324     /**
  1325      * Returns a collection containing threads that may be waiting to
  1326      * acquire the read lock.  Because the actual set of threads may
  1327      * change dynamically while constructing this result, the returned
  1328      * collection is only a best-effort estimate.  The elements of the
  1329      * returned collection are in no particular order.  This method is
  1330      * designed to facilitate construction of subclasses that provide
  1331      * more extensive lock monitoring facilities.
  1332      *
  1333      * @return the collection of threads
  1334      */
  1335     protected Collection<Thread> getQueuedReaderThreads() {
  1336         return sync.getSharedQueuedThreads();
  1337     }
  1338 
  1339     /**
  1340      * Queries whether any threads are waiting to acquire the read or
  1341      * write lock. Note that because cancellations may occur at any
  1342      * time, a {@code true} return does not guarantee that any other
  1343      * thread will ever acquire a lock.  This method is designed
  1344      * primarily for use in monitoring of the system state.
  1345      *
  1346      * @return {@code true} if there may be other threads waiting to
  1347      *         acquire the lock
  1348      */
  1349     public final boolean hasQueuedThreads() {
  1350         return sync.hasQueuedThreads();
  1351     }
  1352 
  1353     /**
  1354      * Queries whether the given thread is waiting to acquire either
  1355      * the read or write lock. Note that because cancellations may
  1356      * occur at any time, a {@code true} return does not guarantee
  1357      * that this thread will ever acquire a lock.  This method is
  1358      * designed primarily for use in monitoring of the system state.
  1359      *
  1360      * @param thread the thread
  1361      * @return {@code true} if the given thread is queued waiting for this lock
  1362      * @throws NullPointerException if the thread is null
  1363      */
  1364     public final boolean hasQueuedThread(Thread thread) {
  1365         return sync.isQueued(thread);
  1366     }
  1367 
  1368     /**
  1369      * Returns an estimate of the number of threads waiting to acquire
  1370      * either the read or write lock.  The value is only an estimate
  1371      * because the number of threads may change dynamically while this
  1372      * method traverses internal data structures.  This method is
  1373      * designed for use in monitoring of the system state, not for
  1374      * synchronization control.
  1375      *
  1376      * @return the estimated number of threads waiting for this lock
  1377      */
  1378     public final int getQueueLength() {
  1379         return sync.getQueueLength();
  1380     }
  1381 
  1382     /**
  1383      * Returns a collection containing threads that may be waiting to
  1384      * acquire either the read or write lock.  Because the actual set
  1385      * of threads may change dynamically while constructing this
  1386      * result, the returned collection is only a best-effort estimate.
  1387      * The elements of the returned collection are in no particular
  1388      * order.  This method is designed to facilitate construction of
  1389      * subclasses that provide more extensive monitoring facilities.
  1390      *
  1391      * @return the collection of threads
  1392      */
  1393     protected Collection<Thread> getQueuedThreads() {
  1394         return sync.getQueuedThreads();
  1395     }
  1396 
  1397     /**
  1398      * Queries whether any threads are waiting on the given condition
  1399      * associated with the write lock. Note that because timeouts and
  1400      * interrupts may occur at any time, a {@code true} return does
  1401      * not guarantee that a future {@code signal} will awaken any
  1402      * threads.  This method is designed primarily for use in
  1403      * monitoring of the system state.
  1404      *
  1405      * @param condition the condition
  1406      * @return {@code true} if there are any waiting threads
  1407      * @throws IllegalMonitorStateException if this lock is not held
  1408      * @throws IllegalArgumentException if the given condition is
  1409      *         not associated with this lock
  1410      * @throws NullPointerException if the condition is null
  1411      */
  1412     public boolean hasWaiters(Condition condition) {
  1413         if (condition == null)
  1414             throw new NullPointerException();
  1415         if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
  1416             throw new IllegalArgumentException("not owner");
  1417         return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
  1418     }
  1419 
  1420     /**
  1421      * Returns an estimate of the number of threads waiting on the
  1422      * given condition associated with the write lock. Note that because
  1423      * timeouts and interrupts may occur at any time, the estimate
  1424      * serves only as an upper bound on the actual number of waiters.
  1425      * This method is designed for use in monitoring of the system
  1426      * state, not for synchronization control.
  1427      *
  1428      * @param condition the condition
  1429      * @return the estimated number of waiting threads
  1430      * @throws IllegalMonitorStateException if this lock is not held
  1431      * @throws IllegalArgumentException if the given condition is
  1432      *         not associated with this lock
  1433      * @throws NullPointerException if the condition is null
  1434      */
  1435     public int getWaitQueueLength(Condition condition) {
  1436         if (condition == null)
  1437             throw new NullPointerException();
  1438         if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
  1439             throw new IllegalArgumentException("not owner");
  1440         return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
  1441     }
  1442 
  1443     /**
  1444      * Returns a collection containing those threads that may be
  1445      * waiting on the given condition associated with the write lock.
  1446      * Because the actual set of threads may change dynamically while
  1447      * constructing this result, the returned collection is only a
  1448      * best-effort estimate. The elements of the returned collection
  1449      * are in no particular order.  This method is designed to
  1450      * facilitate construction of subclasses that provide more
  1451      * extensive condition monitoring facilities.
  1452      *
  1453      * @param condition the condition
  1454      * @return the collection of threads
  1455      * @throws IllegalMonitorStateException if this lock is not held
  1456      * @throws IllegalArgumentException if the given condition is
  1457      *         not associated with this lock
  1458      * @throws NullPointerException if the condition is null
  1459      */
  1460     protected Collection<Thread> getWaitingThreads(Condition condition) {
  1461         if (condition == null)
  1462             throw new NullPointerException();
  1463         if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
  1464             throw new IllegalArgumentException("not owner");
  1465         return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
  1466     }
  1467 
  1468     /**
  1469      * Returns a string identifying this lock, as well as its lock state.
  1470      * The state, in brackets, includes the String {@code "Write locks ="}
  1471      * followed by the number of reentrantly held write locks, and the
  1472      * String {@code "Read locks ="} followed by the number of held
  1473      * read locks.
  1474      *
  1475      * @return a string identifying this lock, as well as its lock state
  1476      */
  1477     public String toString() {
  1478         int c = sync.getCount();
  1479         int w = Sync.exclusiveCount(c);
  1480         int r = Sync.sharedCount(c);
  1481 
  1482         return super.toString() +
  1483             "[Write locks = " + w + ", Read locks = " + r + "]";
  1484     }
  1485 
  1486 }