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