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