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;
   38   import java.util.concurrent;
   39   import java.util.concurrent.atomic;
   40   
   41   /**
   42    * A reentrant mutual exclusion {@link Lock} with the same basic
   43    * behavior and semantics as the implicit monitor lock accessed using
   44    * {@code synchronized} methods and statements, but with extended
   45    * capabilities.
   46    *
   47    * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
   48    * successfully locking, but not yet unlocking it. A thread invoking
   49    * {@code lock} will return, successfully acquiring the lock, when
   50    * the lock is not owned by another thread. The method will return
   51    * immediately if the current thread already owns the lock. This can
   52    * be checked using methods {@link #isHeldByCurrentThread}, and {@link
   53    * #getHoldCount}.
   54    *
   55    * <p>The constructor for this class accepts an optional
   56    * <em>fairness</em> parameter.  When set {@code true}, under
   57    * contention, locks favor granting access to the longest-waiting
   58    * thread.  Otherwise this lock does not guarantee any particular
   59    * access order.  Programs using fair locks accessed by many threads
   60    * may display lower overall throughput (i.e., are slower; often much
   61    * slower) than those using the default setting, but have smaller
   62    * variances in times to obtain locks and guarantee lack of
   63    * starvation. Note however, that fairness of locks does not guarantee
   64    * fairness of thread scheduling. Thus, one of many threads using a
   65    * fair lock may obtain it multiple times in succession while other
   66    * active threads are not progressing and not currently holding the
   67    * lock.
   68    * Also note that the untimed {@link #tryLock() tryLock} method does not
   69    * honor the fairness setting. It will succeed if the lock
   70    * is available even if other threads are waiting.
   71    *
   72    * <p>It is recommended practice to <em>always</em> immediately
   73    * follow a call to {@code lock} with a {@code try} block, most
   74    * typically in a before/after construction such as:
   75    *
   76    * <pre>
   77    * class X {
   78    *   private final ReentrantLock lock = new ReentrantLock();
   79    *   // ...
   80    *
   81    *   public void m() {
   82    *     lock.lock();  // block until condition holds
   83    *     try {
   84    *       // ... method body
   85    *     } finally {
   86    *       lock.unlock()
   87    *     }
   88    *   }
   89    * }
   90    * </pre>
   91    *
   92    * <p>In addition to implementing the {@link Lock} interface, this
   93    * class defines methods {@code isLocked} and
   94    * {@code getLockQueueLength}, as well as some associated
   95    * {@code protected} access methods that may be useful for
   96    * instrumentation and monitoring.
   97    *
   98    * <p>Serialization of this class behaves in the same way as built-in
   99    * locks: a deserialized lock is in the unlocked state, regardless of
  100    * its state when serialized.
  101    *
  102    * <p>This lock supports a maximum of 2147483647 recursive locks by
  103    * the same thread. Attempts to exceed this limit result in
  104    * {@link Error} throws from locking methods.
  105    *
  106    * @since 1.5
  107    * @author Doug Lea
  108    */
  109   public class ReentrantLock implements Lock, java.io.Serializable {
  110       private static final long serialVersionUID = 7373984872572414699L;
  111       /** Synchronizer providing all implementation mechanics */
  112       private final Sync sync;
  113   
  114       /**
  115        * Base of synchronization control for this lock. Subclassed
  116        * into fair and nonfair versions below. Uses AQS state to
  117        * represent the number of holds on the lock.
  118        */
  119       abstract static class Sync extends AbstractQueuedSynchronizer {
  120           private static final long serialVersionUID = -5179523762034025860L;
  121   
  122           /**
  123            * Performs {@link Lock#lock}. The main reason for subclassing
  124            * is to allow fast path for nonfair version.
  125            */
  126           abstract void lock();
  127   
  128           /**
  129            * Performs non-fair tryLock.  tryAcquire is
  130            * implemented in subclasses, but both need nonfair
  131            * try for trylock method.
  132            */
  133           final boolean nonfairTryAcquire(int acquires) {
  134               final Thread current = Thread.currentThread();
  135               int c = getState();
  136               if (c == 0) {
  137                   if (compareAndSetState(0, acquires)) {
  138                       setExclusiveOwnerThread(current);
  139                       return true;
  140                   }
  141               }
  142               else if (current == getExclusiveOwnerThread()) {
  143                   int nextc = c + acquires;
  144                   if (nextc < 0) // overflow
  145                       throw new Error("Maximum lock count exceeded");
  146                   setState(nextc);
  147                   return true;
  148               }
  149               return false;
  150           }
  151   
  152           protected final boolean tryRelease(int releases) {
  153               int c = getState() - releases;
  154               if (Thread.currentThread() != getExclusiveOwnerThread())
  155                   throw new IllegalMonitorStateException();
  156               boolean free = false;
  157               if (c == 0) {
  158                   free = true;
  159                   setExclusiveOwnerThread(null);
  160               }
  161               setState(c);
  162               return free;
  163           }
  164   
  165           protected final boolean isHeldExclusively() {
  166               // While we must in general read state before owner,
  167               // we don't need to do so to check if current thread is owner
  168               return getExclusiveOwnerThread() == Thread.currentThread();
  169           }
  170   
  171           final ConditionObject newCondition() {
  172               return new ConditionObject();
  173           }
  174   
  175           // Methods relayed from outer class
  176   
  177           final Thread getOwner() {
  178               return getState() == 0 ? null : getExclusiveOwnerThread();
  179           }
  180   
  181           final int getHoldCount() {
  182               return isHeldExclusively() ? getState() : 0;
  183           }
  184   
  185           final boolean isLocked() {
  186               return getState() != 0;
  187           }
  188   
  189           /**
  190            * Reconstitutes this lock instance from a stream.
  191            * @param s the stream
  192            */
  193           private void readObject(java.io.ObjectInputStream s)
  194               throws java.io.IOException, ClassNotFoundException {
  195               s.defaultReadObject();
  196               setState(0); // reset to unlocked state
  197           }
  198       }
  199   
  200       /**
  201        * Sync object for non-fair locks
  202        */
  203       static final class NonfairSync extends Sync {
  204           private static final long serialVersionUID = 7316153563782823691L;
  205   
  206           /**
  207            * Performs lock.  Try immediate barge, backing up to normal
  208            * acquire on failure.
  209            */
  210           final void lock() {
  211               if (compareAndSetState(0, 1))
  212                   setExclusiveOwnerThread(Thread.currentThread());
  213               else
  214                   acquire(1);
  215           }
  216   
  217           protected final boolean tryAcquire(int acquires) {
  218               return nonfairTryAcquire(acquires);
  219           }
  220       }
  221   
  222       /**
  223        * Sync object for fair locks
  224        */
  225       static final class FairSync extends Sync {
  226           private static final long serialVersionUID = -3000897897090466540L;
  227   
  228           final void lock() {
  229               acquire(1);
  230           }
  231   
  232           /**
  233            * Fair version of tryAcquire.  Don't grant access unless
  234            * recursive call or no waiters or is first.
  235            */
  236           protected final boolean tryAcquire(int acquires) {
  237               final Thread current = Thread.currentThread();
  238               int c = getState();
  239               if (c == 0) {
  240                   if (!hasQueuedPredecessors() &&
  241                       compareAndSetState(0, acquires)) {
  242                       setExclusiveOwnerThread(current);
  243                       return true;
  244                   }
  245               }
  246               else if (current == getExclusiveOwnerThread()) {
  247                   int nextc = c + acquires;
  248                   if (nextc < 0)
  249                       throw new Error("Maximum lock count exceeded");
  250                   setState(nextc);
  251                   return true;
  252               }
  253               return false;
  254           }
  255       }
  256   
  257       /**
  258        * Creates an instance of {@code ReentrantLock}.
  259        * This is equivalent to using {@code ReentrantLock(false)}.
  260        */
  261       public ReentrantLock() {
  262           sync = new NonfairSync();
  263       }
  264   
  265       /**
  266        * Creates an instance of {@code ReentrantLock} with the
  267        * given fairness policy.
  268        *
  269        * @param fair {@code true} if this lock should use a fair ordering policy
  270        */
  271       public ReentrantLock(boolean fair) {
  272           sync = fair ? new FairSync() : new NonfairSync();
  273       }
  274   
  275       /**
  276        * Acquires the lock.
  277        *
  278        * <p>Acquires the lock if it is not held by another thread and returns
  279        * immediately, setting the lock hold count to one.
  280        *
  281        * <p>If the current thread already holds the lock then the hold
  282        * count is incremented by one and the method returns immediately.
  283        *
  284        * <p>If the lock is held by another thread then the
  285        * current thread becomes disabled for thread scheduling
  286        * purposes and lies dormant until the lock has been acquired,
  287        * at which time the lock hold count is set to one.
  288        */
  289       public void lock() {
  290           sync.lock();
  291       }
  292   
  293       /**
  294        * Acquires the lock unless the current thread is
  295        * {@linkplain Thread#interrupt interrupted}.
  296        *
  297        * <p>Acquires the lock if it is not held by another thread and returns
  298        * immediately, setting the lock hold count to one.
  299        *
  300        * <p>If the current thread already holds this lock then the hold count
  301        * is incremented by one and the method returns immediately.
  302        *
  303        * <p>If the lock is held by another thread then the
  304        * current thread becomes disabled for thread scheduling
  305        * purposes and lies dormant until one of two things happens:
  306        *
  307        * <ul>
  308        *
  309        * <li>The lock is acquired by the current thread; or
  310        *
  311        * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
  312        * current thread.
  313        *
  314        * </ul>
  315        *
  316        * <p>If the lock is acquired by the current thread then the lock hold
  317        * count is set to one.
  318        *
  319        * <p>If the current thread:
  320        *
  321        * <ul>
  322        *
  323        * <li>has its interrupted status set on entry to this method; or
  324        *
  325        * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
  326        * the lock,
  327        *
  328        * </ul>
  329        *
  330        * then {@link InterruptedException} is thrown and the current thread's
  331        * interrupted status is cleared.
  332        *
  333        * <p>In this implementation, as this method is an explicit
  334        * interruption point, preference is given to responding to the
  335        * interrupt over normal or reentrant acquisition of the lock.
  336        *
  337        * @throws InterruptedException if the current thread is interrupted
  338        */
  339       public void lockInterruptibly() throws InterruptedException {
  340           sync.acquireInterruptibly(1);
  341       }
  342   
  343       /**
  344        * Acquires the lock only if it is not held by another thread at the time
  345        * of invocation.
  346        *
  347        * <p>Acquires the lock if it is not held by another thread and
  348        * returns immediately with the value {@code true}, setting the
  349        * lock hold count to one. Even when this lock has been set to use a
  350        * fair ordering policy, a call to {@code tryLock()} <em>will</em>
  351        * immediately acquire the lock if it is available, whether or not
  352        * other threads are currently waiting for the lock.
  353        * This &quot;barging&quot; behavior can be useful in certain
  354        * circumstances, even though it breaks fairness. If you want to honor
  355        * the fairness setting for this lock, then use
  356        * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
  357        * which is almost equivalent (it also detects interruption).
  358        *
  359        * <p> If the current thread already holds this lock then the hold
  360        * count is incremented by one and the method returns {@code true}.
  361        *
  362        * <p>If the lock is held by another thread then this method will return
  363        * immediately with the value {@code false}.
  364        *
  365        * @return {@code true} if the lock was free and was acquired by the
  366        *         current thread, or the lock was already held by the current
  367        *         thread; and {@code false} otherwise
  368        */
  369       public boolean tryLock() {
  370           return sync.nonfairTryAcquire(1);
  371       }
  372   
  373       /**
  374        * Acquires the lock if it is not held by another thread within the given
  375        * waiting time and the current thread has not been
  376        * {@linkplain Thread#interrupt interrupted}.
  377        *
  378        * <p>Acquires the lock if it is not held by another thread and returns
  379        * immediately with the value {@code true}, setting the lock hold count
  380        * to one. If this lock has been set to use a fair ordering policy then
  381        * an available lock <em>will not</em> be acquired if any other threads
  382        * are waiting for the lock. This is in contrast to the {@link #tryLock()}
  383        * method. If you want a timed {@code tryLock} that does permit barging on
  384        * a fair lock then combine the timed and un-timed forms together:
  385        *
  386        * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
  387        * </pre>
  388        *
  389        * <p>If the current thread
  390        * already holds this lock then the hold count is incremented by one and
  391        * the method returns {@code true}.
  392        *
  393        * <p>If the lock is held by another thread then the
  394        * current thread becomes disabled for thread scheduling
  395        * purposes and lies dormant until one of three things happens:
  396        *
  397        * <ul>
  398        *
  399        * <li>The lock is acquired by the current thread; or
  400        *
  401        * <li>Some other thread {@linkplain Thread#interrupt interrupts}
  402        * the current thread; or
  403        *
  404        * <li>The specified waiting time elapses
  405        *
  406        * </ul>
  407        *
  408        * <p>If the lock is acquired then the value {@code true} is returned and
  409        * the lock hold count is set to one.
  410        *
  411        * <p>If the current thread:
  412        *
  413        * <ul>
  414        *
  415        * <li>has its interrupted status set on entry to this method; or
  416        *
  417        * <li>is {@linkplain Thread#interrupt interrupted} while
  418        * acquiring the lock,
  419        *
  420        * </ul>
  421        * then {@link InterruptedException} is thrown and the current thread's
  422        * interrupted status is cleared.
  423        *
  424        * <p>If the specified waiting time elapses then the value {@code false}
  425        * is returned.  If the time is less than or equal to zero, the method
  426        * will not wait at all.
  427        *
  428        * <p>In this implementation, as this method is an explicit
  429        * interruption point, preference is given to responding to the
  430        * interrupt over normal or reentrant acquisition of the lock, and
  431        * over reporting the elapse of the waiting time.
  432        *
  433        * @param timeout the time to wait for the lock
  434        * @param unit the time unit of the timeout argument
  435        * @return {@code true} if the lock was free and was acquired by the
  436        *         current thread, or the lock was already held by the current
  437        *         thread; and {@code false} if the waiting time elapsed before
  438        *         the lock could be acquired
  439        * @throws InterruptedException if the current thread is interrupted
  440        * @throws NullPointerException if the time unit is null
  441        *
  442        */
  443       public boolean tryLock(long timeout, TimeUnit unit)
  444               throws InterruptedException {
  445           return sync.tryAcquireNanos(1, unit.toNanos(timeout));
  446       }
  447   
  448       /**
  449        * Attempts to release this lock.
  450        *
  451        * <p>If the current thread is the holder of this lock then the hold
  452        * count is decremented.  If the hold count is now zero then the lock
  453        * is released.  If the current thread is not the holder of this
  454        * lock then {@link IllegalMonitorStateException} is thrown.
  455        *
  456        * @throws IllegalMonitorStateException if the current thread does not
  457        *         hold this lock
  458        */
  459       public void unlock() {
  460           sync.release(1);
  461       }
  462   
  463       /**
  464        * Returns a {@link Condition} instance for use with this
  465        * {@link Lock} instance.
  466        *
  467        * <p>The returned {@link Condition} instance supports the same
  468        * usages as do the {@link Object} monitor methods ({@link
  469        * Object#wait() wait}, {@link Object#notify notify}, and {@link
  470        * Object#notifyAll notifyAll}) when used with the built-in
  471        * monitor lock.
  472        *
  473        * <ul>
  474        *
  475        * <li>If this lock is not held when any of the {@link Condition}
  476        * {@linkplain Condition#await() waiting} or {@linkplain
  477        * Condition#signal signalling} methods are called, then an {@link
  478        * IllegalMonitorStateException} is thrown.
  479        *
  480        * <li>When the condition {@linkplain Condition#await() waiting}
  481        * methods are called the lock is released and, before they
  482        * return, the lock is reacquired and the lock hold count restored
  483        * to what it was when the method was called.
  484        *
  485        * <li>If a thread is {@linkplain Thread#interrupt interrupted}
  486        * while waiting then the wait will terminate, an {@link
  487        * InterruptedException} will be thrown, and the thread's
  488        * interrupted status will be cleared.
  489        *
  490        * <li> Waiting threads are signalled in FIFO order.
  491        *
  492        * <li>The ordering of lock reacquisition for threads returning
  493        * from waiting methods is the same as for threads initially
  494        * acquiring the lock, which is in the default case not specified,
  495        * but for <em>fair</em> locks favors those threads that have been
  496        * waiting the longest.
  497        *
  498        * </ul>
  499        *
  500        * @return the Condition object
  501        */
  502       public Condition newCondition() {
  503           return sync.newCondition();
  504       }
  505   
  506       /**
  507        * Queries the number of holds on this lock by the current thread.
  508        *
  509        * <p>A thread has a hold on a lock for each lock action that is not
  510        * matched by an unlock action.
  511        *
  512        * <p>The hold count information is typically only used for testing and
  513        * debugging purposes. For example, if a certain section of code should
  514        * not be entered with the lock already held then we can assert that
  515        * fact:
  516        *
  517        * <pre>
  518        * class X {
  519        *   ReentrantLock lock = new ReentrantLock();
  520        *   // ...
  521        *   public void m() {
  522        *     assert lock.getHoldCount() == 0;
  523        *     lock.lock();
  524        *     try {
  525        *       // ... method body
  526        *     } finally {
  527        *       lock.unlock();
  528        *     }
  529        *   }
  530        * }
  531        * </pre>
  532        *
  533        * @return the number of holds on this lock by the current thread,
  534        *         or zero if this lock is not held by the current thread
  535        */
  536       public int getHoldCount() {
  537           return sync.getHoldCount();
  538       }
  539   
  540       /**
  541        * Queries if this lock is held by the current thread.
  542        *
  543        * <p>Analogous to the {@link Thread#holdsLock} method for built-in
  544        * monitor locks, this method is typically used for debugging and
  545        * testing. For example, a method that should only be called while
  546        * a lock is held can assert that this is the case:
  547        *
  548        * <pre>
  549        * class X {
  550        *   ReentrantLock lock = new ReentrantLock();
  551        *   // ...
  552        *
  553        *   public void m() {
  554        *       assert lock.isHeldByCurrentThread();
  555        *       // ... method body
  556        *   }
  557        * }
  558        * </pre>
  559        *
  560        * <p>It can also be used to ensure that a reentrant lock is used
  561        * in a non-reentrant manner, for example:
  562        *
  563        * <pre>
  564        * class X {
  565        *   ReentrantLock lock = new ReentrantLock();
  566        *   // ...
  567        *
  568        *   public void m() {
  569        *       assert !lock.isHeldByCurrentThread();
  570        *       lock.lock();
  571        *       try {
  572        *           // ... method body
  573        *       } finally {
  574        *           lock.unlock();
  575        *       }
  576        *   }
  577        * }
  578        * </pre>
  579        *
  580        * @return {@code true} if current thread holds this lock and
  581        *         {@code false} otherwise
  582        */
  583       public boolean isHeldByCurrentThread() {
  584           return sync.isHeldExclusively();
  585       }
  586   
  587       /**
  588        * Queries if this lock is held by any thread. This method is
  589        * designed for use in monitoring of the system state,
  590        * not for synchronization control.
  591        *
  592        * @return {@code true} if any thread holds this lock and
  593        *         {@code false} otherwise
  594        */
  595       public boolean isLocked() {
  596           return sync.isLocked();
  597       }
  598   
  599       /**
  600        * Returns {@code true} if this lock has fairness set true.
  601        *
  602        * @return {@code true} if this lock has fairness set true
  603        */
  604       public final boolean isFair() {
  605           return sync instanceof FairSync;
  606       }
  607   
  608       /**
  609        * Returns the thread that currently owns this lock, or
  610        * {@code null} if not owned. When this method is called by a
  611        * thread that is not the owner, the return value reflects a
  612        * best-effort approximation of current lock status. For example,
  613        * the owner may be momentarily {@code null} even if there are
  614        * threads trying to acquire the lock but have not yet done so.
  615        * This method is designed to facilitate construction of
  616        * subclasses that provide more extensive lock monitoring
  617        * facilities.
  618        *
  619        * @return the owner, or {@code null} if not owned
  620        */
  621       protected Thread getOwner() {
  622           return sync.getOwner();
  623       }
  624   
  625       /**
  626        * Queries whether any threads are waiting to acquire this lock. Note that
  627        * because cancellations may occur at any time, a {@code true}
  628        * return does not guarantee that any other thread will ever
  629        * acquire this lock.  This method is designed primarily for use in
  630        * monitoring of the system state.
  631        *
  632        * @return {@code true} if there may be other threads waiting to
  633        *         acquire the lock
  634        */
  635       public final boolean hasQueuedThreads() {
  636           return sync.hasQueuedThreads();
  637       }
  638   
  639   
  640       /**
  641        * Queries whether the given thread is waiting to acquire this
  642        * lock. Note that because cancellations may occur at any time, a
  643        * {@code true} return does not guarantee that this thread
  644        * will ever acquire this lock.  This method is designed primarily for use
  645        * in monitoring of the system state.
  646        *
  647        * @param thread the thread
  648        * @return {@code true} if the given thread is queued waiting for this lock
  649        * @throws NullPointerException if the thread is null
  650        */
  651       public final boolean hasQueuedThread(Thread thread) {
  652           return sync.isQueued(thread);
  653       }
  654   
  655   
  656       /**
  657        * Returns an estimate of the number of threads waiting to
  658        * acquire this lock.  The value is only an estimate because the number of
  659        * threads may change dynamically while this method traverses
  660        * internal data structures.  This method is designed for use in
  661        * monitoring of the system state, not for synchronization
  662        * control.
  663        *
  664        * @return the estimated number of threads waiting for this lock
  665        */
  666       public final int getQueueLength() {
  667           return sync.getQueueLength();
  668       }
  669   
  670       /**
  671        * Returns a collection containing threads that may be waiting to
  672        * acquire this lock.  Because the actual set of threads may change
  673        * dynamically while constructing this result, the returned
  674        * collection is only a best-effort estimate.  The elements of the
  675        * returned collection are in no particular order.  This method is
  676        * designed to facilitate construction of subclasses that provide
  677        * more extensive monitoring facilities.
  678        *
  679        * @return the collection of threads
  680        */
  681       protected Collection<Thread> getQueuedThreads() {
  682           return sync.getQueuedThreads();
  683       }
  684   
  685       /**
  686        * Queries whether any threads are waiting on the given condition
  687        * associated with this lock. Note that because timeouts and
  688        * interrupts may occur at any time, a {@code true} return does
  689        * not guarantee that a future {@code signal} will awaken any
  690        * threads.  This method is designed primarily for use in
  691        * monitoring of the system state.
  692        *
  693        * @param condition the condition
  694        * @return {@code true} if there are any waiting threads
  695        * @throws IllegalMonitorStateException if this lock is not held
  696        * @throws IllegalArgumentException if the given condition is
  697        *         not associated with this lock
  698        * @throws NullPointerException if the condition is null
  699        */
  700       public boolean hasWaiters(Condition condition) {
  701           if (condition == null)
  702               throw new NullPointerException();
  703           if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
  704               throw new IllegalArgumentException("not owner");
  705           return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
  706       }
  707   
  708       /**
  709        * Returns an estimate of the number of threads waiting on the
  710        * given condition associated with this lock. Note that because
  711        * timeouts and interrupts may occur at any time, the estimate
  712        * serves only as an upper bound on the actual number of waiters.
  713        * This method is designed for use in monitoring of the system
  714        * state, not for synchronization control.
  715        *
  716        * @param condition the condition
  717        * @return the estimated number of waiting threads
  718        * @throws IllegalMonitorStateException if this lock is not held
  719        * @throws IllegalArgumentException if the given condition is
  720        *         not associated with this lock
  721        * @throws NullPointerException if the condition is null
  722        */
  723       public int getWaitQueueLength(Condition condition) {
  724           if (condition == null)
  725               throw new NullPointerException();
  726           if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
  727               throw new IllegalArgumentException("not owner");
  728           return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
  729       }
  730   
  731       /**
  732        * Returns a collection containing those threads that may be
  733        * waiting on the given condition associated with this lock.
  734        * Because the actual set of threads may change dynamically while
  735        * constructing this result, the returned collection is only a
  736        * best-effort estimate. The elements of the returned collection
  737        * are in no particular order.  This method is designed to
  738        * facilitate construction of subclasses that provide more
  739        * extensive condition monitoring facilities.
  740        *
  741        * @param condition the condition
  742        * @return the collection of threads
  743        * @throws IllegalMonitorStateException if this lock is not held
  744        * @throws IllegalArgumentException if the given condition is
  745        *         not associated with this lock
  746        * @throws NullPointerException if the condition is null
  747        */
  748       protected Collection<Thread> getWaitingThreads(Condition condition) {
  749           if (condition == null)
  750               throw new NullPointerException();
  751           if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
  752               throw new IllegalArgumentException("not owner");
  753           return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
  754       }
  755   
  756       /**
  757        * Returns a string identifying this lock, as well as its lock state.
  758        * The state, in brackets, includes either the String {@code "Unlocked"}
  759        * or the String {@code "Locked by"} followed by the
  760        * {@linkplain Thread#getName name} of the owning thread.
  761        *
  762        * @return a string identifying this lock, as well as its lock state
  763        */
  764       public String toString() {
  765           Thread o = sync.getOwner();
  766           return super.toString() + ((o == null) ?
  767                                      "[Unlocked]" :
  768                                      "[Locked by thread " + o.getName() + "]");
  769       }
  770   }

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