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    }