Save This Page
Home » openjdk-7 » java » util » concurrent » locks » [javadoc | source]
    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   }

Save This Page
Home » openjdk-7 » java » util » concurrent » locks » [javadoc | source]