    001    /*
    002     * Copyright (C) 2010 The Guava Authors
    003     *
    004     * Licensed under the Apache License, Version 2.0 (the "License");
    005     * you may not use this file except in compliance with the License.
    006     * You may obtain a copy of the License at
    007     *
    008     * http://www.apache.org/licenses/LICENSE-2.0
    009     *
    010     * Unless required by applicable law or agreed to in writing, software
    011     * distributed under the License is distributed on an "AS IS" BASIS,
    012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    013     * See the License for the specific language governing permissions and
    014     * limitations under the License.
    015     */
    016
    017    package com.google.common.util.concurrent;
    018
    019    import static com.google.common.base.Preconditions.checkNotNull;
    020
    021    import com.google.common.annotations.Beta;
    022    import com.google.common.base.Throwables;
    023    import com.google.common.collect.Lists;
    024
    025    import java.util.ArrayList;
    026    import java.util.concurrent.TimeUnit;
    027    import java.util.concurrent.locks.Condition;
    028    import java.util.concurrent.locks.ReentrantLock;
    029
    030    import javax.annotation.Nullable;
    031    import javax.annotation.concurrent.GuardedBy;
    032
    033    /**
    034     * A synchronization abstraction supporting waiting on arbitrary boolean conditions.
    035     *
    036     * <p>This class is intended as a replacement for {@link ReentrantLock}. Code using {@code Monitor}
    037     * is less error-prone and more readable than code using {@code ReentrantLock}, without significant
    038     * performance loss. {@code Monitor} even has the potential for performance gain by optimizing the
    039     * evaluation and signaling of conditions.  Signaling is entirely
    040     * <a href="http://en.wikipedia.org/wiki/Monitor_(synchronization)#Implicit_signaling">
    041     * implicit</a>.
    042     * By eliminating explicit signaling, this class can guarantee that only one thread is awakened
    043     * when a condition becomes true (no "signaling storms" due to use of {@link
    044     * java.util.concurrent.locks.Condition#signalAll Condition.signalAll}) and that no signals are lost
    045     * (no "hangs" due to incorrect use of {@link java.util.concurrent.locks.Condition#signal
    046     * Condition.signal}).
    047     *
    048     * <p>A thread is said to <i>occupy</i> a monitor if it has <i>entered</i> the monitor but not yet
    049     * <i>left</i>. Only one thread may occupy a given monitor at any moment. A monitor is also
    050     * reentrant, so a thread may enter a monitor any number of times, and then must leave the same
    051     * number of times. The <i>enter</i> and <i>leave</i> operations have the same synchronization
    052     * semantics as the built-in Java language synchronization primitives.
    053     *
    054     * <p>A call to any of the <i>enter</i> methods with <b>void</b> return type should always be
    055     * followed immediately by a <i>try/finally</i> block to ensure that the current thread leaves the
    056     * monitor cleanly: <pre>   {@code
    057     *
    058     *   monitor.enter();
    059     *   try {
    060     *     // do things while occupying the monitor
    061     *   } finally {
    062     *     monitor.leave();
    063     *   }}</pre>
    064     *
    065     * A call to any of the <i>enter</i> methods with <b>boolean</b> return type should always appear as
    066     * the condition of an <i>if</i> statement containing a <i>try/finally</i> block to ensure that the
    067     * current thread leaves the monitor cleanly: <pre>   {@code
    068     *
    069     *   if (monitor.tryEnter()) {
    070     *     try {
    071     *       // do things while occupying the monitor
    072     *     } finally {
    073     *       monitor.leave();
    074     *     }
    075     *   } else {
    076     *     // do other things since the monitor was not available
    077     *   }}</pre>
    078     *
    079     * <h2>Comparison with {@code synchronized} and {@code ReentrantLock}</h2>
    080     *
    081     * <p>The following examples show a simple threadsafe holder expressed using {@code synchronized},
    082     * {@link ReentrantLock}, and {@code Monitor}.
    083     *
    084     * <h3>{@code synchronized}</h3>
    085     *
    086     * <p>This version is the fewest lines of code, largely because the synchronization mechanism used
    087     * is built into the language and runtime. But the programmer has to remember to avoid a couple of
    088     * common bugs: The {@code wait()} must be inside a {@code while} instead of an {@code if}, and
    089     * {@code notifyAll()} must be used instead of {@code notify()} because there are two different
    090     * logical conditions being awaited. <pre>   {@code
    091     *
    092     *   public class SafeBox<V> {
    093     *     private V value;
    094     *
    095     *     public synchronized V get() throws InterruptedException {
    096     *       while (value == null) {
    097     *         wait();
    098     *       }
    099     *       V result = value;
    100     *       value = null;
    101     *       notifyAll();
    102     *       return result;
    103     *     }
    104     *
    105     *     public synchronized void set(V newValue) throws InterruptedException {
    106     *       while (value != null) {
    107     *         wait();
    108     *       }
    109     *       value = newValue;
    110     *       notifyAll();
    111     *     }
    112     *   }}</pre>
    113     *
    114     * <h3>{@code ReentrantLock}</h3>
    115     *
    116     * <p>This version is much more verbose than the {@code synchronized} version, and still suffers
    117     * from the need for the programmer to remember to use {@code while} instead of {@code if}.
    118     * However, one advantage is that we can introduce two separate {@code Condition} objects, which
    119     * allows us to use {@code signal()} instead of {@code signalAll()}, which may be a performance
    120     * benefit. <pre>   {@code
    121     *
    122     *   public class SafeBox<V> {
    123     *     private final ReentrantLock lock = new ReentrantLock();
    124     *     private final Condition valuePresent = lock.newCondition();
    125     *     private final Condition valueAbsent = lock.newCondition();
    126     *     private V value;
    127     *
    128     *     public V get() throws InterruptedException {
    129     *       lock.lock();
    130     *       try {
    131     *         while (value == null) {
    132     *           valuePresent.await();
    133     *         }
    134     *         V result = value;
    135     *         value = null;
    136     *         valueAbsent.signal();
    137     *         return result;
    138     *       } finally {
    139     *         lock.unlock();
    140     *       }
    141     *     }
    142     *
    143     *     public void set(V newValue) throws InterruptedException {
    144     *       lock.lock();
    145     *       try {
    146     *         while (value != null) {
    147     *           valueAbsent.await();
    148     *         }
    149     *         value = newValue;
    150     *         valuePresent.signal();
    151     *       } finally {
    152     *         lock.unlock();
    153     *       }
    154     *     }
    155     *   }}</pre>
    156     *
    157     * <h3>{@code Monitor}</h3>
    158     *
    159     * <p>This version adds some verbosity around the {@code Guard} objects, but removes that same
    160     * verbosity, and more, from the {@code get} and {@code set} methods. {@code Monitor} implements the
    161     * same efficient signaling as we had to hand-code in the {@code ReentrantLock} version above.
    162     * Finally, the programmer no longer has to hand-code the wait loop, and therefore doesn't have to
    163     * remember to use {@code while} instead of {@code if}. <pre>   {@code
    164     *
    165     *   public class SafeBox<V> {
    166     *     private final Monitor monitor = new Monitor();
    167     *     private final Monitor.Guard valuePresent = new Monitor.Guard(monitor) {
    168     *       public boolean isSatisfied() {
    169     *         return value != null;
    170     *       }
    171     *     };
    172     *     private final Monitor.Guard valueAbsent = new Monitor.Guard(monitor) {
    173     *       public boolean isSatisfied() {
    174     *         return value == null;
    175     *       }
    176     *     };
    177     *     private V value;
    178     *
    179     *     public V get() throws InterruptedException {
    180     *       monitor.enterWhen(valuePresent);
    181     *       try {
    182     *         V result = value;
    183     *         value = null;
    184     *         return result;
    185     *       } finally {
    186     *         monitor.leave();
    187     *       }
    188     *     }
    189     *
    190     *     public void set(V newValue) throws InterruptedException {
    191     *       monitor.enterWhen(valueAbsent);
    192     *       try {
    193     *         value = newValue;
    194     *       } finally {
    195     *         monitor.leave();
    196     *       }
    197     *     }
    198     *   }}</pre>
    199     *
    200     * @author Justin T. Sampson
    201     * @since 10.0
    202     */
    203    @Beta
    204    public final class Monitor {
    205      // TODO: Use raw LockSupport or AbstractQueuedSynchronizer instead of ReentrantLock.
    206
    207      /**
    208       * A boolean condition for which a thread may wait. A {@code Guard} is associated with a single
    209       * {@code Monitor}. The monitor may check the guard at arbitrary times from any thread occupying
    210       * the monitor, so code should not be written to rely on how often a guard might or might not be
    211       * checked.
    212       *
    213       * <p>If a {@code Guard} is passed into any method of a {@code Monitor} other than the one it is
    214       * associated with, an {@link IllegalMonitorStateException} is thrown.
    215       *
    216       * @since 10.0
    217       */
    218      @Beta
    219      public abstract static class Guard {
    220
    221        final Monitor monitor;
    222        final Condition condition;
    223
    224        @GuardedBy("monitor.lock")
    225        int waiterCount = 0;
    226
    227        protected Guard(Monitor monitor) {
    228          this.monitor = checkNotNull(monitor, "monitor");
    229          this.condition = monitor.lock.newCondition();
    230        }
    231
    232        /**
    233         * Evaluates this guard's boolean condition. This method is always called with the associated
    234         * monitor already occupied. Implementations of this method must depend only on state protected
    235         * by the associated monitor, and must not modify that state.
    236         */
    237        public abstract boolean isSatisfied();
    238
    239        @Override
    240        public final boolean equals(Object other) {
    241          // Overridden as final to ensure identity semantics in Monitor.activeGuards.
    242          return this == other;
    243        }
    244
    245        @Override
    246        public final int hashCode() {
    247          // Overridden as final to ensure identity semantics in Monitor.activeGuards.
    248          return super.hashCode();
    249        }
    250
    251      }
    252
    253      /**
    254       * Whether this monitor is fair.
    255       */
    256      private final boolean fair;
    257
    258      /**
    259       * The lock underlying this monitor.
    260       */
    261      private final ReentrantLock lock;
    262
    263      /**
    264       * The guards associated with this monitor that currently have waiters ({@code waiterCount > 0}).
    265       * This is an ArrayList rather than, say, a HashSet so that iteration and almost all adds don't
    266       * incur any object allocation overhead.
    267       */
    268      @GuardedBy("lock")
    269      private final ArrayList<Guard> activeGuards = Lists.newArrayListWithCapacity(1);
    270
    271      /**
    272       * Creates a monitor with a non-fair (but fast) ordering policy. Equivalent to {@code
    273       * Monitor(false)}.
    274       */
    275      public Monitor() {
    276        this(false);
    277      }
    278
    279      /**
    280       * Creates a monitor with the given ordering policy.
    281       *
    282       * @param fair whether this monitor should use a fair ordering policy rather than a non-fair (but
    283       *        fast) one
    284       */
    285      public Monitor(boolean fair) {
    286        this.fair = fair;
    287        this.lock = new ReentrantLock(fair);
    288      }
    289
    290      /**
    291       * Enters this monitor. Blocks indefinitely.
    292       */
    293      public void enter() {
    294        lock.lock();
    295      }
    296
    297      /**
    298       * Enters this monitor. Blocks indefinitely, but may be interrupted.
    299       */
    300      public void enterInterruptibly() throws InterruptedException {
    301        lock.lockInterruptibly();
    302      }
    303
    304      /**
    305       * Enters this monitor. Blocks at most the given time.
    306       *
    307       * @return whether the monitor was entered
    308       */
    309      public boolean enter(long time, TimeUnit unit) {
    310        final ReentrantLock lock = this.lock;
    311        if (!fair && lock.tryLock()) {
    312          return true;
    313        }
    314        long startNanos = System.nanoTime();
    315        long timeoutNanos = unit.toNanos(time);
    316        long remainingNanos = timeoutNanos;
    317        boolean interruptIgnored = false;
    318        try {
    319          while (true) {
    320            try {
    321              return lock.tryLock(remainingNanos, TimeUnit.NANOSECONDS);
    322            } catch (InterruptedException ignored) {
    323              interruptIgnored = true;
    324              remainingNanos = (timeoutNanos - (System.nanoTime() - startNanos));
    325            }
    326          }
    327        } finally {
    328          if (interruptIgnored) {
    329            Thread.currentThread().interrupt();
    330          }
    331        }
    332      }
    333
    334      /**
    335       * Enters this monitor. Blocks at most the given time, and may be interrupted.
    336       *
    337       * @return whether the monitor was entered
    338       */
    339      public boolean enterInterruptibly(long time, TimeUnit unit) throws InterruptedException {
    340        return lock.tryLock(time, unit);
    341      }
    342
    343      /**
    344       * Enters this monitor if it is possible to do so immediately. Does not block.
    345       *
    346       * <p><b>Note:</b> This method disregards the fairness setting of this monitor.
    347       *
    348       * @return whether the monitor was entered
    349       */
    350      public boolean tryEnter() {
    351        return lock.tryLock();
    352      }
    353
    354      /**
    355       * Enters this monitor when the guard is satisfied. Blocks indefinitely, but may be interrupted.
    356       */
    357      public void enterWhen(Guard guard) throws InterruptedException {
    358        if (guard.monitor != this) {
    359          throw new IllegalMonitorStateException();
    360        }
    361        final ReentrantLock lock = this.lock;
    362        boolean reentrant = lock.isHeldByCurrentThread();
    363        boolean success = false;
    364        lock.lockInterruptibly();
    365        try {
    366          waitInterruptibly(guard, reentrant);
    367          success = true;
    368        } finally {
    369          if (!success) {
    370            lock.unlock();
    371          }
    372        }
    373      }
    374
    375      /**
    376       * Enters this monitor when the guard is satisfied. Blocks indefinitely.
    377       */
    378      public void enterWhenUninterruptibly(Guard guard) {
    379        if (guard.monitor != this) {
    380          throw new IllegalMonitorStateException();
    381        }
    382        final ReentrantLock lock = this.lock;
    383        boolean reentrant = lock.isHeldByCurrentThread();
    384        boolean success = false;
    385        lock.lock();
    386        try {
    387          waitUninterruptibly(guard, reentrant);
    388          success = true;
    389        } finally {
    390          if (!success) {
    391            lock.unlock();
    392          }
    393        }
    394      }
    395
    396      /**
    397       * Enters this monitor when the guard is satisfied. Blocks at most the given time, including both
    398       * the time to acquire the lock and the time to wait for the guard to be satisfied, and may be
    399       * interrupted.
    400       *
    401       * @return whether the monitor was entered
    402       */
    403      public boolean enterWhen(Guard guard, long time, TimeUnit unit) throws InterruptedException {
    404        if (guard.monitor != this) {
    405          throw new IllegalMonitorStateException();
    406        }
    407        final ReentrantLock lock = this.lock;
    408        boolean reentrant = lock.isHeldByCurrentThread();
    409        long remainingNanos;
    410        if (!fair && lock.tryLock()) {
    411          remainingNanos = unit.toNanos(time);
    412        } else {
    413          long startNanos = System.nanoTime();
    414          if (!lock.tryLock(time, unit)) {
    415            return false;
    416          }
    417          remainingNanos = unit.toNanos(time) - (System.nanoTime() - startNanos);
    418        }
    419        boolean satisfied = false;
    420        try {
    421          satisfied = waitInterruptibly(guard, remainingNanos, reentrant);
    422        } finally {
    423          if (!satisfied) {
    424            lock.unlock();
    425          }
    426        }
    427        return satisfied;
    428      }
    429
    430      /**
    431       * Enters this monitor when the guard is satisfied. Blocks at most the given time, including
    432       * both the time to acquire the lock and the time to wait for the guard to be satisfied.
    433       *
    434       * @return whether the monitor was entered
    435       */
    436      public boolean enterWhenUninterruptibly(Guard guard, long time, TimeUnit unit) {
    437        if (guard.monitor != this) {
    438          throw new IllegalMonitorStateException();
    439        }
    440        final ReentrantLock lock = this.lock;
    441        boolean reentrant = lock.isHeldByCurrentThread();
    442        boolean interruptIgnored = false;
    443        try {
    444          long remainingNanos;
    445          if (!fair && lock.tryLock()) {
    446            remainingNanos = unit.toNanos(time);
    447          } else {
    448            long startNanos = System.nanoTime();
    449            long timeoutNanos = unit.toNanos(time);
    450            remainingNanos = timeoutNanos;
    451            while (true) {
    452              try {
    453                if (lock.tryLock(remainingNanos, TimeUnit.NANOSECONDS)) {
    454                  break;
    455                } else {
    456                  return false;
    457                }
    458              } catch (InterruptedException ignored) {
    459                interruptIgnored = true;
    460              } finally {
    461                remainingNanos = (timeoutNanos - (System.nanoTime() - startNanos));
    462              }
    463            }
    464          }
    465          boolean satisfied = false;
    466          try {
    467            satisfied = waitUninterruptibly(guard, remainingNanos, reentrant);
    468          } finally {
    469            if (!satisfied) {
    470              lock.unlock();
    471            }
    472          }
    473          return satisfied;
    474        } finally {
    475          if (interruptIgnored) {
    476            Thread.currentThread().interrupt();
    477          }
    478        }
    479      }
    480
    481      /**
    482       * Enters this monitor if the guard is satisfied. Blocks indefinitely acquiring the lock, but
    483       * does not wait for the guard to be satisfied.
    484       *
    485       * @return whether the monitor was entered
    486       */
    487      public boolean enterIf(Guard guard) {
    488        if (guard.monitor != this) {
    489          throw new IllegalMonitorStateException();
    490        }
    491        final ReentrantLock lock = this.lock;
    492        lock.lock();
    493        boolean satisfied = false;
    494        try {
    495          satisfied = guard.isSatisfied();
    496        } finally {
    497          if (!satisfied) {
    498            lock.unlock();
    499          }
    500        }
    501        return satisfied;
    502      }
    503
    504      /**
    505       * Enters this monitor if the guard is satisfied. Blocks indefinitely acquiring the lock, but does
    506       * not wait for the guard to be satisfied, and may be interrupted.
    507       *
    508       * @return whether the monitor was entered
    509       */
    510      public boolean enterIfInterruptibly(Guard guard) throws InterruptedException {
    511        if (guard.monitor != this) {
    512          throw new IllegalMonitorStateException();
    513        }
    514        final ReentrantLock lock = this.lock;
    515        lock.lockInterruptibly();
    516        boolean satisfied = false;
    517        try {
    518          satisfied = guard.isSatisfied();
    519        } finally {
    520          if (!satisfied) {
    521            lock.unlock();
    522          }
    523        }
    524        return satisfied;
    525      }
    526
    527      /**
    528       * Enters this monitor if the guard is satisfied. Blocks at most the given time acquiring the
    529       * lock, but does not wait for the guard to be satisfied.
    530       *
    531       * @return whether the monitor was entered
    532       */
    533      public boolean enterIf(Guard guard, long time, TimeUnit unit) {
    534        if (guard.monitor != this) {
    535          throw new IllegalMonitorStateException();
    536        }
    537        final ReentrantLock lock = this.lock;
    538        if (!enter(time, unit)) {
    539          return false;
    540        }
    541        boolean satisfied = false;
    542        try {
    543          satisfied = guard.isSatisfied();
    544        } finally {
    545          if (!satisfied) {
    546            lock.unlock();
    547          }
    548        }
    549        return satisfied;
    550      }
    551
    552      /**
    553       * Enters this monitor if the guard is satisfied. Blocks at most the given time acquiring the
    554       * lock, but does not wait for the guard to be satisfied, and may be interrupted.
    555       *
    556       * @return whether the monitor was entered
    557       */
    558      public boolean enterIfInterruptibly(Guard guard, long time, TimeUnit unit)
    559          throws InterruptedException {
    560        if (guard.monitor != this) {
    561          throw new IllegalMonitorStateException();
    562        }
    563        final ReentrantLock lock = this.lock;
    564        if (!lock.tryLock(time, unit)) {
    565          return false;
    566        }
    567        boolean satisfied = false;
    568        try {
    569          satisfied = guard.isSatisfied();
    570        } finally {
    571          if (!satisfied) {
    572            lock.unlock();
    573          }
    574        }
    575        return satisfied;
    576      }
    577
    578      /**
    579       * Enters this monitor if it is possible to do so immediately and the guard is satisfied. Does not
    580       * block acquiring the lock and does not wait for the guard to be satisfied.
    581       *
    582       * <p><b>Note:</b> This method disregards the fairness setting of this monitor.
    583       *
    584       * @return whether the monitor was entered
    585       */
    586      public boolean tryEnterIf(Guard guard) {
    587        if (guard.monitor != this) {
    588          throw new IllegalMonitorStateException();
    589        }
    590        final ReentrantLock lock = this.lock;
    591        if (!lock.tryLock()) {
    592          return false;
    593        }
    594        boolean satisfied = false;
    595        try {
    596          satisfied = guard.isSatisfied();
    597        } finally {
    598          if (!satisfied) {
    599            lock.unlock();
    600          }
    601        }
    602        return satisfied;
    603      }
    604
    605      /**
    606       * Waits for the guard to be satisfied. Waits indefinitely, but may be interrupted. May be
    607       * called only by a thread currently occupying this monitor.
    608       */
    609      public void waitFor(Guard guard) throws InterruptedException {
    610        if (guard.monitor != this) {
    611          throw new IllegalMonitorStateException();
    612        }
    613        if (!lock.isHeldByCurrentThread()) {
    614          throw new IllegalMonitorStateException();
    615        }
    616        waitInterruptibly(guard, true);
    617      }
    618
    619      /**
    620       * Waits for the guard to be satisfied. Waits indefinitely. May be called only by a thread
    621       * currently occupying this monitor.
    622       */
    623      public void waitForUninterruptibly(Guard guard) {
    624        if (guard.monitor != this) {
    625          throw new IllegalMonitorStateException();
    626        }
    627        if (!lock.isHeldByCurrentThread()) {
    628          throw new IllegalMonitorStateException();
    629        }
    630        waitUninterruptibly(guard, true);
    631      }
    632
    633      /**
    634       * Waits for the guard to be satisfied. Waits at most the given time, and may be interrupted.
    635       * May be called only by a thread currently occupying this monitor.
    636       *
    637       * @return whether the guard is now satisfied
    638       */
    639      public boolean waitFor(Guard guard, long time, TimeUnit unit) throws InterruptedException {
    640        if (guard.monitor != this) {
    641          throw new IllegalMonitorStateException();
    642        }
    643        if (!lock.isHeldByCurrentThread()) {
    644          throw new IllegalMonitorStateException();
    645        }
    646        return waitInterruptibly(guard, unit.toNanos(time), true);
    647      }
    648
    649      /**
    650       * Waits for the guard to be satisfied. Waits at most the given time. May be called only by a
    651       * thread currently occupying this monitor.
    652       *
    653       * @return whether the guard is now satisfied
    654       */
    655      public boolean waitForUninterruptibly(Guard guard, long time, TimeUnit unit) {
    656        if (guard.monitor != this) {
    657          throw new IllegalMonitorStateException();
    658        }
    659        if (!lock.isHeldByCurrentThread()) {
    660          throw new IllegalMonitorStateException();
    661        }
    662        return waitUninterruptibly(guard, unit.toNanos(time), true);
    663      }
    664
    665      /**
    666       * Leaves this monitor. May be called only by a thread currently occupying this monitor.
    667       */
    668      public void leave() {
    669        final ReentrantLock lock = this.lock;
    670        if (!lock.isHeldByCurrentThread()) {
    671          throw new IllegalMonitorStateException();
    672        }
    673        try {
    674          signalConditionsOfSatisfiedGuards(null);
    675        } finally {
    676          lock.unlock();
    677        }
    678      }
    679
    680      /**
    681       * Returns whether this monitor is using a fair ordering policy.
    682       */
    683      public boolean isFair() {
    684        return lock.isFair();
    685      }
    686
    687      /**
    688       * Returns whether this monitor is occupied by any thread. This method is designed for use in
    689       * monitoring of the system state, not for synchronization control.
    690       */
    691      public boolean isOccupied() {
    692        return lock.isLocked();
    693      }
    694
    695      /**
    696       * Returns whether the current thread is occupying this monitor (has entered more times than it
    697       * has left).
    698       */
    699      public boolean isOccupiedByCurrentThread() {
    700        return lock.isHeldByCurrentThread();
    701      }
    702
    703      /**
    704       * Returns the number of times the current thread has entered this monitor in excess of the number
    705       * of times it has left. Returns 0 if the current thread is not occupying this monitor.
    706       */
    707      public int getOccupiedDepth() {
    708        return lock.getHoldCount();
    709      }
    710
    711      /**
    712       * Returns an estimate of the number of threads waiting to enter this monitor. The value is only
    713       * an estimate because the number of threads may change dynamically while this method traverses
    714       * internal data structures. This method is designed for use in monitoring of the system state,
    715       * not for synchronization control.
    716       */
    717      public int getQueueLength() {
    718        return lock.getQueueLength();
    719      }
    720
    721      /**
    722       * Returns whether any threads are waiting to enter this monitor. Note that because cancellations
    723       * may occur at any time, a {@code true} return does not guarantee that any other thread will ever
    724       * enter this monitor. This method is designed primarily for use in monitoring of the system
    725       * state.
    726       */
    727      public boolean hasQueuedThreads() {
    728        return lock.hasQueuedThreads();
    729      }
    730
    731      /**
    732       * Queries whether the given thread is waiting to enter this monitor. Note that because
    733       * cancellations may occur at any time, a {@code true} return does not guarantee that this thread
    734       * will ever enter this monitor. This method is designed primarily for use in monitoring of the
    735       * system state.
    736       */
    737      public boolean hasQueuedThread(Thread thread) {
    738        return lock.hasQueuedThread(thread);
    739      }
    740
    741      /**
    742       * Queries whether any threads are waiting for the given guard to become satisfied. Note that
    743       * because timeouts and interrupts may occur at any time, a {@code true} return does not guarantee
    744       * that the guard becoming satisfied in the future will awaken any threads. This method is
    745       * designed primarily for use in monitoring of the system state.
    746       */
    747      public boolean hasWaiters(Guard guard) {
    748        if (guard.monitor != this) {
    749          throw new IllegalMonitorStateException();
    750        }
    751        lock.lock();
    752        try {
    753          return guard.waiterCount > 0;
    754        } finally {
    755          lock.unlock();
    756        }
    757      }
    758
    759      /**
    760       * Returns an estimate of the number of threads waiting for the given guard to become satisfied.
    761       * Note that because timeouts and interrupts may occur at any time, the estimate serves only as an
    762       * upper bound on the actual number of waiters. This method is designed for use in monitoring of
    763       * the system state, not for synchronization control.
    764       */
    765      public int getWaitQueueLength(Guard guard) {
    766        if (guard.monitor != this) {
    767          throw new IllegalMonitorStateException();
    768        }
    769        lock.lock();
    770        try {
    771          return guard.waiterCount;
    772        } finally {
    773          lock.unlock();
    774        }
    775      }
    776
    777      @GuardedBy("lock")
    778      private void signalConditionsOfSatisfiedGuards(@Nullable Guard interruptedGuard) {
    779        final ArrayList<Guard> guards = this.activeGuards;
    780        final int guardCount = guards.size();
    781        try {
    782          for (int i = 0; i < guardCount; i++) {
    783            Guard guard = guards.get(i);
    784            if ((guard == interruptedGuard) && (guard.waiterCount == 1)) {
    785              // That one waiter was just interrupted and is throwing InterruptedException rather than
    786              // paying attention to the guard being satisfied, so find another waiter on another guard.
    787              continue;
    788            }
    789            if (guard.isSatisfied()) {
    790              guard.condition.signal();
    791              return;
    792            }
    793          }
    794        } catch (Throwable throwable) {
    795          for (int i = 0; i < guardCount; i++) {
    796            Guard guard = guards.get(i);
    797            guard.condition.signalAll();
    798          }
    799          throw Throwables.propagate(throwable);
    800        }
    801      }
    802
    803      @GuardedBy("lock")
    804      private void incrementWaiters(Guard guard) {
    805        int waiters = guard.waiterCount++;
    806        if (waiters == 0) {
    807          activeGuards.add(guard);
    808        }
    809      }
    810
    811      @GuardedBy("lock")
    812      private void decrementWaiters(Guard guard) {
    813        int waiters = --guard.waiterCount;
    814        if (waiters == 0) {
    815          activeGuards.remove(guard);
    816        }
    817      }
    818
    819      @GuardedBy("lock")
    820      private void waitInterruptibly(Guard guard, boolean signalBeforeWaiting)
    821          throws InterruptedException {
    822        if (!guard.isSatisfied()) {
    823          if (signalBeforeWaiting) {
    824            signalConditionsOfSatisfiedGuards(null);
    825          }
    826          incrementWaiters(guard);
    827          try {
    828            final Condition condition = guard.condition;
    829            do {
    830              try {
    831                condition.await();
    832              } catch (InterruptedException interrupt) {
    833                try {
    834                  signalConditionsOfSatisfiedGuards(guard);
    835                } catch (Throwable throwable) {
    836                  Thread.currentThread().interrupt();
    837                  throw Throwables.propagate(throwable);
    838                }
    839                throw interrupt;
    840              }
    841            } while (!guard.isSatisfied());
    842          } finally {
    843            decrementWaiters(guard);
    844          }
    845        }
    846      }
    847
    848      @GuardedBy("lock")
    849      private void waitUninterruptibly(Guard guard, boolean signalBeforeWaiting) {
    850        if (!guard.isSatisfied()) {
    851          if (signalBeforeWaiting) {
    852            signalConditionsOfSatisfiedGuards(null);
    853          }
    854          incrementWaiters(guard);
    855          try {
    856            final Condition condition = guard.condition;
    857            do {
    858              condition.awaitUninterruptibly();
    859            } while (!guard.isSatisfied());
    860          } finally {
    861            decrementWaiters(guard);
    862          }
    863        }
    864      }
    865
    866      @GuardedBy("lock")
    867      private boolean waitInterruptibly(Guard guard, long remainingNanos, boolean signalBeforeWaiting)
    868          throws InterruptedException {
    869        if (!guard.isSatisfied()) {
    870          if (signalBeforeWaiting) {
    871            signalConditionsOfSatisfiedGuards(null);
    872          }
    873          incrementWaiters(guard);
    874          try {
    875            final Condition condition = guard.condition;
    876            do {
    877              if (remainingNanos <= 0) {
    878                return false;
    879              }
    880              try {
    881                remainingNanos = condition.awaitNanos(remainingNanos);
    882              } catch (InterruptedException interrupt) {
    883                try {
    884                  signalConditionsOfSatisfiedGuards(guard);
    885                } catch (Throwable throwable) {
    886                  Thread.currentThread().interrupt();
    887                  throw Throwables.propagate(throwable);
    888                }
    889                throw interrupt;
    890              }
    891            } while (!guard.isSatisfied());
    892          } finally {
    893            decrementWaiters(guard);
    894          }
    895        }
    896        return true;
    897      }
    898
    899      @GuardedBy("lock")
    900      private boolean waitUninterruptibly(Guard guard, long timeoutNanos,
    901          boolean signalBeforeWaiting) {
    902        if (!guard.isSatisfied()) {
    903          long startNanos = System.nanoTime();
    904          if (signalBeforeWaiting) {
    905            signalConditionsOfSatisfiedGuards(null);
    906          }
    907          boolean interruptIgnored = false;
    908          try {
    909            incrementWaiters(guard);
    910            try {
    911              final Condition condition = guard.condition;
    912              long remainingNanos = timeoutNanos;
    913              do {
    914                if (remainingNanos <= 0) {
    915                  return false;
    916                }
    917                try {
    918                  remainingNanos = condition.awaitNanos(remainingNanos);
    919                } catch (InterruptedException ignored) {
    920                  try {
    921                    signalConditionsOfSatisfiedGuards(guard);
    922                  } catch (Throwable throwable) {
    923                    Thread.currentThread().interrupt();
    924                    throw Throwables.propagate(throwable);
    925                  }
    926                  interruptIgnored = true;
    927                  remainingNanos = (timeoutNanos - (System.nanoTime() - startNanos));
    928                }
    929              } while (!guard.isSatisfied());
    930            } finally {
    931              decrementWaiters(guard);
    932            }
    933          } finally {
    934            if (interruptIgnored) {
    935              Thread.currentThread().interrupt();
    936            }
    937          }
    938        }
    939        return true;
    940      }
    941
    942    }