• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package com.google.common.util.concurrent;
16 
17 import static com.google.common.base.Preconditions.checkNotNull;
18 
19 import com.google.common.annotations.GwtIncompatible;
20 import com.google.common.annotations.J2ktIncompatible;
21 import com.google.common.primitives.Longs;
22 import com.google.errorprone.annotations.concurrent.GuardedBy;
23 import com.google.j2objc.annotations.Weak;
24 import java.util.concurrent.TimeUnit;
25 import java.util.concurrent.locks.Condition;
26 import java.util.concurrent.locks.ReentrantLock;
27 import javax.annotation.CheckForNull;
28 
29 /**
30  * A synchronization abstraction supporting waiting on arbitrary boolean conditions.
31  *
32  * <p>This class is intended as a replacement for {@link ReentrantLock}. Code using {@code Monitor}
33  * is less error-prone and more readable than code using {@code ReentrantLock}, without significant
34  * performance loss. {@code Monitor} even has the potential for performance gain by optimizing the
35  * evaluation and signaling of conditions. Signaling is entirely <a
36  * href="http://en.wikipedia.org/wiki/Monitor_(synchronization)#Implicit_signaling">implicit</a>. By
37  * eliminating explicit signaling, this class can guarantee that only one thread is awakened when a
38  * condition becomes true (no "signaling storms" due to use of {@link
39  * java.util.concurrent.locks.Condition#signalAll Condition.signalAll}) and that no signals are lost
40  * (no "hangs" due to incorrect use of {@link java.util.concurrent.locks.Condition#signal
41  * Condition.signal}).
42  *
43  * <p>A thread is said to <i>occupy</i> a monitor if it has <i>entered</i> the monitor but not yet
44  * <i>left</i>. Only one thread may occupy a given monitor at any moment. A monitor is also
45  * reentrant, so a thread may enter a monitor any number of times, and then must leave the same
46  * number of times. The <i>enter</i> and <i>leave</i> operations have the same synchronization
47  * semantics as the built-in Java language synchronization primitives.
48  *
49  * <p>A call to any of the <i>enter</i> methods with <b>void</b> return type should always be
50  * followed immediately by a <i>try/finally</i> block to ensure that the current thread leaves the
51  * monitor cleanly:
52  *
53  * <pre>{@code
54  * monitor.enter();
55  * try {
56  *   // do things while occupying the monitor
57  * } finally {
58  *   monitor.leave();
59  * }
60  * }</pre>
61  *
62  * <p>A call to any of the <i>enter</i> methods with <b>boolean</b> return type should always appear
63  * as the condition of an <i>if</i> statement containing a <i>try/finally</i> block to ensure that
64  * the current thread leaves the monitor cleanly:
65  *
66  * <pre>{@code
67  * if (monitor.tryEnter()) {
68  *   try {
69  *     // do things while occupying the monitor
70  *   } finally {
71  *     monitor.leave();
72  *   }
73  * } else {
74  *   // do other things since the monitor was not available
75  * }
76  * }</pre>
77  *
78  * <h2>Comparison with {@code synchronized} and {@code ReentrantLock}</h2>
79  *
80  * <p>The following examples show a simple threadsafe holder expressed using {@code synchronized},
81  * {@link ReentrantLock}, and {@code Monitor}.
82  *
83  * <h3>{@code synchronized}</h3>
84  *
85  * <p>This version is the fewest lines of code, largely because the synchronization mechanism used
86  * is built into the language and runtime. But the programmer has to remember to avoid a couple of
87  * common bugs: The {@code wait()} must be inside a {@code while} instead of an {@code if}, and
88  * {@code notifyAll()} must be used instead of {@code notify()} because there are two different
89  * logical conditions being awaited.
90  *
91  * <pre>{@code
92  * public class SafeBox<V> {
93  *   private V value;
94  *
95  *   public synchronized V get() throws InterruptedException {
96  *     while (value == null) {
97  *       wait();
98  *     }
99  *     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  * }
113  * }</pre>
114  *
115  * <h3>{@code ReentrantLock}</h3>
116  *
117  * <p>This version is much more verbose than the {@code synchronized} version, and still suffers
118  * from the need for the programmer to remember to use {@code while} instead of {@code if}. However,
119  * one advantage is that we can introduce two separate {@code Condition} objects, which allows us to
120  * use {@code signal()} instead of {@code signalAll()}, which may be a performance benefit.
121  *
122  * <pre>{@code
123  * public class SafeBox<V> {
124  *   private V value;
125  *   private final ReentrantLock lock = new ReentrantLock();
126  *   private final Condition valuePresent = lock.newCondition();
127  *   private final Condition valueAbsent = lock.newCondition();
128  *
129  *   public V get() throws InterruptedException {
130  *     lock.lock();
131  *     try {
132  *       while (value == null) {
133  *         valuePresent.await();
134  *       }
135  *       V result = value;
136  *       value = null;
137  *       valueAbsent.signal();
138  *       return result;
139  *     } finally {
140  *       lock.unlock();
141  *     }
142  *   }
143  *
144  *   public void set(V newValue) throws InterruptedException {
145  *     lock.lock();
146  *     try {
147  *       while (value != null) {
148  *         valueAbsent.await();
149  *       }
150  *       value = newValue;
151  *       valuePresent.signal();
152  *     } finally {
153  *       lock.unlock();
154  *     }
155  *   }
156  * }
157  * }</pre>
158  *
159  * <h3>{@code Monitor}</h3>
160  *
161  * <p>This version adds some verbosity around the {@code Guard} objects, but removes that same
162  * verbosity, and more, from the {@code get} and {@code set} methods. {@code Monitor} implements the
163  * same efficient signaling as we had to hand-code in the {@code ReentrantLock} version above.
164  * Finally, the programmer no longer has to hand-code the wait loop, and therefore doesn't have to
165  * remember to use {@code while} instead of {@code if}.
166  *
167  * <pre>{@code
168  * public class SafeBox<V> {
169  *   private V value;
170  *   private final Monitor monitor = new Monitor();
171  *   private final Monitor.Guard valuePresent = monitor.newGuard(() -> value != null);
172  *   private final Monitor.Guard valueAbsent = monitor.newGuard(() -> value == null);
173  *
174  *   public V get() throws InterruptedException {
175  *     monitor.enterWhen(valuePresent);
176  *     try {
177  *       V result = value;
178  *       value = null;
179  *       return result;
180  *     } finally {
181  *       monitor.leave();
182  *     }
183  *   }
184  *
185  *   public void set(V newValue) throws InterruptedException {
186  *     monitor.enterWhen(valueAbsent);
187  *     try {
188  *       value = newValue;
189  *     } finally {
190  *       monitor.leave();
191  *     }
192  *   }
193  * }
194  * }</pre>
195  *
196  * @author Justin T. Sampson
197  * @author Martin Buchholz
198  * @since 10.0
199  */
200 @J2ktIncompatible
201 @GwtIncompatible
202 @SuppressWarnings("GuardedBy") // TODO(b/35466881): Fix or suppress.
203 @ElementTypesAreNonnullByDefault
204 public final class Monitor {
205   // TODO(user): Use raw LockSupport or AbstractQueuedSynchronizer instead of ReentrantLock.
206   // TODO(user): "Port" jsr166 tests for ReentrantLock.
207   //
208   // TODO(user): Change API to make it impossible to use a Guard with the "wrong" monitor,
209   //    by making the monitor implicit, and to eliminate other sources of IMSE.
210   //    Imagine:
211   //    guard.lock();
212   //    try { /* monitor locked and guard satisfied here */ }
213   //    finally { guard.unlock(); }
214   // Here are Justin's design notes about this:
215   //
216   // This idea has come up from time to time, and I think one of my
217   // earlier versions of Monitor even did something like this. I ended
218   // up strongly favoring the current interface.
219   //
220   // I probably can't remember all the reasons (it's possible you
221   // could find them in the code review archives), but here are a few:
222   //
223   // 1. What about leaving/unlocking? Are you going to do
224   //    guard.enter() paired with monitor.leave()? That might get
225   //    confusing. It's nice for the finally block to look as close as
226   //    possible to the thing right before the try. You could have
227   //    guard.leave(), but that's a little odd as well because the
228   //    guard doesn't have anything to do with leaving. You can't
229   //    really enforce that the guard you're leaving is the same one
230   //    you entered with, and it doesn't actually matter.
231   //
232   // 2. Since you can enter the monitor without a guard at all, some
233   //    places you'll have monitor.enter()/monitor.leave() and other
234   //    places you'll have guard.enter()/guard.leave() even though
235   //    it's the same lock being acquired underneath. Always using
236   //    monitor.enterXXX()/monitor.leave() will make it really clear
237   //    which lock is held at any point in the code.
238   //
239   // 3. I think "enterWhen(notEmpty)" reads better than "notEmpty.enter()".
240   //
241   // TODO(user): Implement ReentrantLock features:
242   //    - toString() method
243   //    - getOwner() method
244   //    - getQueuedThreads() method
245   //    - getWaitingThreads(Guard) method
246   //    - implement Serializable
247   //    - redo the API to be as close to identical to ReentrantLock as possible,
248   //      since, after all, this class is also a reentrant mutual exclusion lock!?
249 
250   /*
251    * One of the key challenges of this class is to prevent lost signals, while trying hard to
252    * minimize unnecessary signals. One simple and correct algorithm is to signal some other waiter
253    * with a satisfied guard (if one exists) whenever any thread occupying the monitor exits the
254    * monitor, either by unlocking all of its held locks, or by starting to wait for a guard. This
255    * includes exceptional exits, so all control paths involving signalling must be protected by a
256    * finally block.
257    *
258    * Further optimizations of this algorithm become increasingly subtle. A wait that terminates
259    * without the guard being satisfied (due to timeout, but not interrupt) can then immediately exit
260    * the monitor without signalling. If it timed out without being signalled, it does not need to
261    * "pass on" the signal to another thread. If it *was* signalled, then its guard must have been
262    * satisfied at the time of signal, and has since been modified by some other thread to be
263    * non-satisfied before reacquiring the lock, and that other thread takes over the responsibility
264    * of signaling the next waiter.
265    *
266    * Unlike the underlying Condition, if we are not careful, an interrupt *can* cause a signal to be
267    * lost, because the signal may be sent to a condition whose sole waiter has just been
268    * interrupted.
269    *
270    * Imagine a monitor with multiple guards. A thread enters the monitor, satisfies all the guards,
271    * and leaves, calling signalNextWaiter. With traditional locks and conditions, all the conditions
272    * need to be signalled because it is not known which if any of them have waiters (and hasWaiters
273    * can't be used reliably because of a check-then-act race). With our Monitor guards, we only
274    * signal the first active guard that is satisfied. But the corresponding thread may have already
275    * been interrupted and is waiting to reacquire the lock while still registered in activeGuards,
276    * in which case the signal is a no-op, and the bigger-picture signal is lost unless interrupted
277    * threads take special action by participating in the signal-passing game.
278    */
279 
280   /*
281    * Timeout handling is intricate, especially given our ambitious goals:
282    * - Avoid underflow and overflow of timeout values when specified timeouts are close to
283    *   Long.MIN_VALUE or Long.MAX_VALUE.
284    * - Favor responding to interrupts over timeouts.
285    * - System.nanoTime() is expensive enough that we want to call it the minimum required number of
286    *   times, typically once before invoking a blocking method. This often requires keeping track of
287    *   the first time in a method that nanoTime() has been invoked, for which the special value 0L
288    *   is reserved to mean "uninitialized". If timeout is non-positive, then nanoTime need never be
289    *   called.
290    * - Keep behavior of fair and non-fair instances consistent.
291    */
292 
293   /**
294    * A boolean condition for which a thread may wait. A {@code Guard} is associated with a single
295    * {@code Monitor}. The monitor may check the guard at arbitrary times from any thread occupying
296    * the monitor, so code should not be written to rely on how often a guard might or might not be
297    * checked.
298    *
299    * <p>If a {@code Guard} is passed into any method of a {@code Monitor} other than the one it is
300    * associated with, an {@link IllegalMonitorStateException} is thrown.
301    *
302    * @since 10.0
303    */
304   public abstract static class Guard {
305 
306     @Weak final Monitor monitor;
307     final Condition condition;
308 
309     @GuardedBy("monitor.lock")
310     int waiterCount = 0;
311 
312     /** The next active guard */
313     @GuardedBy("monitor.lock")
314     @CheckForNull
315     Guard next;
316 
Guard(Monitor monitor)317     protected Guard(Monitor monitor) {
318       this.monitor = checkNotNull(monitor, "monitor");
319       this.condition = monitor.lock.newCondition();
320     }
321 
322     /**
323      * Evaluates this guard's boolean condition. This method is always called with the associated
324      * monitor already occupied. Implementations of this method must depend only on state protected
325      * by the associated monitor, and must not modify that state.
326      */
isSatisfied()327     public abstract boolean isSatisfied();
328   }
329 
330   /** Whether this monitor is fair. */
331   private final boolean fair;
332 
333   /** The lock underlying this monitor. */
334   private final ReentrantLock lock;
335 
336   /**
337    * The guards associated with this monitor that currently have waiters ({@code waiterCount > 0}).
338    * A linked list threaded through the Guard.next field.
339    */
340   @GuardedBy("lock")
341   @CheckForNull
342   private Guard activeGuards = null;
343 
344   /**
345    * Creates a monitor with a non-fair (but fast) ordering policy. Equivalent to {@code
346    * Monitor(false)}.
347    */
Monitor()348   public Monitor() {
349     this(false);
350   }
351 
352   /**
353    * Creates a monitor with the given ordering policy.
354    *
355    * @param fair whether this monitor should use a fair ordering policy rather than a non-fair (but
356    *     fast) one
357    */
Monitor(boolean fair)358   public Monitor(boolean fair) {
359     this.fair = fair;
360     this.lock = new ReentrantLock(fair);
361   }
362 
363   /** Enters this monitor. Blocks indefinitely. */
enter()364   public void enter() {
365     lock.lock();
366   }
367 
368   /**
369    * Enters this monitor. Blocks at most the given time.
370    *
371    * @return whether the monitor was entered
372    */
373   @SuppressWarnings("GoodTime") // should accept a java.time.Duration
enter(long time, TimeUnit unit)374   public boolean enter(long time, TimeUnit unit) {
375     final long timeoutNanos = toSafeNanos(time, unit);
376     final ReentrantLock lock = this.lock;
377     if (!fair && lock.tryLock()) {
378       return true;
379     }
380     boolean interrupted = Thread.interrupted();
381     try {
382       final long startTime = System.nanoTime();
383       for (long remainingNanos = timeoutNanos; ; ) {
384         try {
385           return lock.tryLock(remainingNanos, TimeUnit.NANOSECONDS);
386         } catch (InterruptedException interrupt) {
387           interrupted = true;
388           remainingNanos = remainingNanos(startTime, timeoutNanos);
389         }
390       }
391     } finally {
392       if (interrupted) {
393         Thread.currentThread().interrupt();
394       }
395     }
396   }
397 
398   /**
399    * Enters this monitor. Blocks indefinitely, but may be interrupted.
400    *
401    * @throws InterruptedException if interrupted while waiting
402    */
enterInterruptibly()403   public void enterInterruptibly() throws InterruptedException {
404     lock.lockInterruptibly();
405   }
406 
407   /**
408    * Enters this monitor. Blocks at most the given time, and may be interrupted.
409    *
410    * @return whether the monitor was entered
411    * @throws InterruptedException if interrupted while waiting
412    */
413   @SuppressWarnings("GoodTime") // should accept a java.time.Duration
enterInterruptibly(long time, TimeUnit unit)414   public boolean enterInterruptibly(long time, TimeUnit unit) throws InterruptedException {
415     return lock.tryLock(time, unit);
416   }
417 
418   /**
419    * Enters this monitor if it is possible to do so immediately. Does not block.
420    *
421    * <p><b>Note:</b> This method disregards the fairness setting of this monitor.
422    *
423    * @return whether the monitor was entered
424    */
tryEnter()425   public boolean tryEnter() {
426     return lock.tryLock();
427   }
428 
429   /**
430    * Enters this monitor when the guard is satisfied. Blocks indefinitely, but may be interrupted.
431    *
432    * @throws InterruptedException if interrupted while waiting
433    */
enterWhen(Guard guard)434   public void enterWhen(Guard guard) throws InterruptedException {
435     if (guard.monitor != this) {
436       throw new IllegalMonitorStateException();
437     }
438     final ReentrantLock lock = this.lock;
439     boolean signalBeforeWaiting = lock.isHeldByCurrentThread();
440     lock.lockInterruptibly();
441 
442     boolean satisfied = false;
443     try {
444       if (!guard.isSatisfied()) {
445         await(guard, signalBeforeWaiting);
446       }
447       satisfied = true;
448     } finally {
449       if (!satisfied) {
450         leave();
451       }
452     }
453   }
454 
455   /**
456    * Enters this monitor when the guard is satisfied. Blocks at most the given time, including both
457    * the time to acquire the lock and the time to wait for the guard to be satisfied, and may be
458    * interrupted.
459    *
460    * @return whether the monitor was entered, which guarantees that the guard is now satisfied
461    * @throws InterruptedException if interrupted while waiting
462    */
463   @SuppressWarnings({
464     "GoodTime", // should accept a java.time.Duration
465     "LabelledBreakTarget", // TODO(b/345814817): Maybe fix.
466   })
enterWhen(Guard guard, long time, TimeUnit unit)467   public boolean enterWhen(Guard guard, long time, TimeUnit unit) throws InterruptedException {
468     final long timeoutNanos = toSafeNanos(time, unit);
469     if (guard.monitor != this) {
470       throw new IllegalMonitorStateException();
471     }
472     final ReentrantLock lock = this.lock;
473     boolean reentrant = lock.isHeldByCurrentThread();
474     long startTime = 0L;
475 
476     locked:
477     {
478       if (!fair) {
479         // Check interrupt status to get behavior consistent with fair case.
480         if (Thread.interrupted()) {
481           throw new InterruptedException();
482         }
483         if (lock.tryLock()) {
484           break locked;
485         }
486       }
487       startTime = initNanoTime(timeoutNanos);
488       if (!lock.tryLock(time, unit)) {
489         return false;
490       }
491     }
492 
493     boolean satisfied = false;
494     boolean threw = true;
495     try {
496       satisfied =
497           guard.isSatisfied()
498               || awaitNanos(
499                   guard,
500                   (startTime == 0L) ? timeoutNanos : remainingNanos(startTime, timeoutNanos),
501                   reentrant);
502       threw = false;
503       return satisfied;
504     } finally {
505       if (!satisfied) {
506         try {
507           // Don't need to signal if timed out, but do if interrupted
508           if (threw && !reentrant) {
509             signalNextWaiter();
510           }
511         } finally {
512           lock.unlock();
513         }
514       }
515     }
516   }
517 
518   /** Enters this monitor when the guard is satisfied. Blocks indefinitely. */
enterWhenUninterruptibly(Guard guard)519   public void enterWhenUninterruptibly(Guard guard) {
520     if (guard.monitor != this) {
521       throw new IllegalMonitorStateException();
522     }
523     final ReentrantLock lock = this.lock;
524     boolean signalBeforeWaiting = lock.isHeldByCurrentThread();
525     lock.lock();
526 
527     boolean satisfied = false;
528     try {
529       if (!guard.isSatisfied()) {
530         awaitUninterruptibly(guard, signalBeforeWaiting);
531       }
532       satisfied = true;
533     } finally {
534       if (!satisfied) {
535         leave();
536       }
537     }
538   }
539 
540   /**
541    * Enters this monitor when the guard is satisfied. Blocks at most the given time, including both
542    * the time to acquire the lock and the time to wait for the guard to be satisfied.
543    *
544    * @return whether the monitor was entered, which guarantees that the guard is now satisfied
545    */
546   @SuppressWarnings("GoodTime") // should accept a java.time.Duration
enterWhenUninterruptibly(Guard guard, long time, TimeUnit unit)547   public boolean enterWhenUninterruptibly(Guard guard, long time, TimeUnit unit) {
548     final long timeoutNanos = toSafeNanos(time, unit);
549     if (guard.monitor != this) {
550       throw new IllegalMonitorStateException();
551     }
552     final ReentrantLock lock = this.lock;
553     long startTime = 0L;
554     boolean signalBeforeWaiting = lock.isHeldByCurrentThread();
555     boolean interrupted = Thread.interrupted();
556     try {
557       if (fair || !lock.tryLock()) {
558         startTime = initNanoTime(timeoutNanos);
559         for (long remainingNanos = timeoutNanos; ; ) {
560           try {
561             if (lock.tryLock(remainingNanos, TimeUnit.NANOSECONDS)) {
562               break;
563             } else {
564               return false;
565             }
566           } catch (InterruptedException interrupt) {
567             interrupted = true;
568             remainingNanos = remainingNanos(startTime, timeoutNanos);
569           }
570         }
571       }
572 
573       boolean satisfied = false;
574       try {
575         while (true) {
576           try {
577             if (guard.isSatisfied()) {
578               satisfied = true;
579             } else {
580               final long remainingNanos;
581               if (startTime == 0L) {
582                 startTime = initNanoTime(timeoutNanos);
583                 remainingNanos = timeoutNanos;
584               } else {
585                 remainingNanos = remainingNanos(startTime, timeoutNanos);
586               }
587               satisfied = awaitNanos(guard, remainingNanos, signalBeforeWaiting);
588             }
589             return satisfied;
590           } catch (InterruptedException interrupt) {
591             interrupted = true;
592             signalBeforeWaiting = false;
593           }
594         }
595       } finally {
596         if (!satisfied) {
597           lock.unlock(); // No need to signal if timed out
598         }
599       }
600     } finally {
601       if (interrupted) {
602         Thread.currentThread().interrupt();
603       }
604     }
605   }
606 
607   /**
608    * Enters this monitor if the guard is satisfied. Blocks indefinitely acquiring the lock, but does
609    * not wait for the guard to be satisfied.
610    *
611    * @return whether the monitor was entered, which guarantees that the guard is now satisfied
612    */
enterIf(Guard guard)613   public boolean enterIf(Guard guard) {
614     if (guard.monitor != this) {
615       throw new IllegalMonitorStateException();
616     }
617     final ReentrantLock lock = this.lock;
618     lock.lock();
619 
620     boolean satisfied = false;
621     try {
622       return satisfied = guard.isSatisfied();
623     } finally {
624       if (!satisfied) {
625         lock.unlock();
626       }
627     }
628   }
629 
630   /**
631    * Enters this monitor if the guard is satisfied. Blocks at most the given time acquiring the
632    * lock, but does not wait for the guard to be satisfied.
633    *
634    * @return whether the monitor was entered, which guarantees that the guard is now satisfied
635    */
636   @SuppressWarnings("GoodTime") // should accept a java.time.Duration
enterIf(Guard guard, long time, TimeUnit unit)637   public boolean enterIf(Guard guard, long time, TimeUnit unit) {
638     if (guard.monitor != this) {
639       throw new IllegalMonitorStateException();
640     }
641     if (!enter(time, unit)) {
642       return false;
643     }
644 
645     boolean satisfied = false;
646     try {
647       return satisfied = guard.isSatisfied();
648     } finally {
649       if (!satisfied) {
650         lock.unlock();
651       }
652     }
653   }
654 
655   /**
656    * Enters this monitor if the guard is satisfied. Blocks indefinitely acquiring the lock, but does
657    * not wait for the guard to be satisfied, and may be interrupted.
658    *
659    * @return whether the monitor was entered, which guarantees that the guard is now satisfied
660    * @throws InterruptedException if interrupted while waiting
661    */
enterIfInterruptibly(Guard guard)662   public boolean enterIfInterruptibly(Guard guard) throws InterruptedException {
663     if (guard.monitor != this) {
664       throw new IllegalMonitorStateException();
665     }
666     final ReentrantLock lock = this.lock;
667     lock.lockInterruptibly();
668 
669     boolean satisfied = false;
670     try {
671       return satisfied = guard.isSatisfied();
672     } finally {
673       if (!satisfied) {
674         lock.unlock();
675       }
676     }
677   }
678 
679   /**
680    * Enters this monitor if the guard is satisfied. Blocks at most the given time acquiring the
681    * lock, but does not wait for the guard to be satisfied, and may be interrupted.
682    *
683    * @return whether the monitor was entered, which guarantees that the guard is now satisfied
684    */
685   @SuppressWarnings("GoodTime") // should accept a java.time.Duration
enterIfInterruptibly(Guard guard, long time, TimeUnit unit)686   public boolean enterIfInterruptibly(Guard guard, long time, TimeUnit unit)
687       throws InterruptedException {
688     if (guard.monitor != this) {
689       throw new IllegalMonitorStateException();
690     }
691     final ReentrantLock lock = this.lock;
692     if (!lock.tryLock(time, unit)) {
693       return false;
694     }
695 
696     boolean satisfied = false;
697     try {
698       return satisfied = guard.isSatisfied();
699     } finally {
700       if (!satisfied) {
701         lock.unlock();
702       }
703     }
704   }
705 
706   /**
707    * Enters this monitor if it is possible to do so immediately and the guard is satisfied. Does not
708    * block acquiring the lock and does not wait for the guard to be satisfied.
709    *
710    * <p><b>Note:</b> This method disregards the fairness setting of this monitor.
711    *
712    * @return whether the monitor was entered, which guarantees that the guard is now satisfied
713    */
tryEnterIf(Guard guard)714   public boolean tryEnterIf(Guard guard) {
715     if (guard.monitor != this) {
716       throw new IllegalMonitorStateException();
717     }
718     final ReentrantLock lock = this.lock;
719     if (!lock.tryLock()) {
720       return false;
721     }
722 
723     boolean satisfied = false;
724     try {
725       return satisfied = guard.isSatisfied();
726     } finally {
727       if (!satisfied) {
728         lock.unlock();
729       }
730     }
731   }
732 
733   /**
734    * Waits for the guard to be satisfied. Waits indefinitely, but may be interrupted. May be called
735    * only by a thread currently occupying this monitor.
736    *
737    * @throws InterruptedException if interrupted while waiting
738    */
waitFor(Guard guard)739   public void waitFor(Guard guard) throws InterruptedException {
740     if (!((guard.monitor == this) && lock.isHeldByCurrentThread())) {
741       throw new IllegalMonitorStateException();
742     }
743     if (!guard.isSatisfied()) {
744       await(guard, true);
745     }
746   }
747 
748   /**
749    * Waits for the guard to be satisfied. Waits at most the given time, and may be interrupted. May
750    * be called only by a thread currently occupying this monitor.
751    *
752    * @return whether the guard is now satisfied
753    * @throws InterruptedException if interrupted while waiting
754    */
755   @SuppressWarnings("GoodTime") // should accept a java.time.Duration
waitFor(Guard guard, long time, TimeUnit unit)756   public boolean waitFor(Guard guard, long time, TimeUnit unit) throws InterruptedException {
757     final long timeoutNanos = toSafeNanos(time, unit);
758     if (!((guard.monitor == this) && lock.isHeldByCurrentThread())) {
759       throw new IllegalMonitorStateException();
760     }
761     if (guard.isSatisfied()) {
762       return true;
763     }
764     if (Thread.interrupted()) {
765       throw new InterruptedException();
766     }
767     return awaitNanos(guard, timeoutNanos, true);
768   }
769 
770   /**
771    * Waits for the guard to be satisfied. Waits indefinitely. May be called only by a thread
772    * currently occupying this monitor.
773    */
waitForUninterruptibly(Guard guard)774   public void waitForUninterruptibly(Guard guard) {
775     if (!((guard.monitor == this) && lock.isHeldByCurrentThread())) {
776       throw new IllegalMonitorStateException();
777     }
778     if (!guard.isSatisfied()) {
779       awaitUninterruptibly(guard, true);
780     }
781   }
782 
783   /**
784    * Waits for the guard to be satisfied. Waits at most the given time. May be called only by a
785    * thread currently occupying this monitor.
786    *
787    * @return whether the guard is now satisfied
788    */
789   @SuppressWarnings("GoodTime") // should accept a java.time.Duration
waitForUninterruptibly(Guard guard, long time, TimeUnit unit)790   public boolean waitForUninterruptibly(Guard guard, long time, TimeUnit unit) {
791     final long timeoutNanos = toSafeNanos(time, unit);
792     if (!((guard.monitor == this) && lock.isHeldByCurrentThread())) {
793       throw new IllegalMonitorStateException();
794     }
795     if (guard.isSatisfied()) {
796       return true;
797     }
798     boolean signalBeforeWaiting = true;
799     final long startTime = initNanoTime(timeoutNanos);
800     boolean interrupted = Thread.interrupted();
801     try {
802       for (long remainingNanos = timeoutNanos; ; ) {
803         try {
804           return awaitNanos(guard, remainingNanos, signalBeforeWaiting);
805         } catch (InterruptedException interrupt) {
806           interrupted = true;
807           if (guard.isSatisfied()) {
808             return true;
809           }
810           signalBeforeWaiting = false;
811           remainingNanos = remainingNanos(startTime, timeoutNanos);
812         }
813       }
814     } finally {
815       if (interrupted) {
816         Thread.currentThread().interrupt();
817       }
818     }
819   }
820 
821   /** Leaves this monitor. May be called only by a thread currently occupying this monitor. */
leave()822   public void leave() {
823     final ReentrantLock lock = this.lock;
824     try {
825       // No need to signal if we will still be holding the lock when we return
826       if (lock.getHoldCount() == 1) {
827         signalNextWaiter();
828       }
829     } finally {
830       lock.unlock(); // Will throw IllegalMonitorStateException if not held
831     }
832   }
833 
834   /** Returns whether this monitor is using a fair ordering policy. */
isFair()835   public boolean isFair() {
836     return fair;
837   }
838 
839   /**
840    * Returns whether this monitor is occupied by any thread. This method is designed for use in
841    * monitoring of the system state, not for synchronization control.
842    */
isOccupied()843   public boolean isOccupied() {
844     return lock.isLocked();
845   }
846 
847   /**
848    * Returns whether the current thread is occupying this monitor (has entered more times than it
849    * has left).
850    */
isOccupiedByCurrentThread()851   public boolean isOccupiedByCurrentThread() {
852     return lock.isHeldByCurrentThread();
853   }
854 
855   /**
856    * Returns the number of times the current thread has entered this monitor in excess of the number
857    * of times it has left. Returns 0 if the current thread is not occupying this monitor.
858    */
getOccupiedDepth()859   public int getOccupiedDepth() {
860     return lock.getHoldCount();
861   }
862 
863   /**
864    * Returns an estimate of the number of threads waiting to enter this monitor. The value is only
865    * an estimate because the number of threads may change dynamically while this method traverses
866    * internal data structures. This method is designed for use in monitoring of the system state,
867    * not for synchronization control.
868    */
getQueueLength()869   public int getQueueLength() {
870     return lock.getQueueLength();
871   }
872 
873   /**
874    * Returns whether any threads are waiting to enter this monitor. Note that because cancellations
875    * may occur at any time, a {@code true} return does not guarantee that any other thread will ever
876    * enter this monitor. This method is designed primarily for use in monitoring of the system
877    * state.
878    */
hasQueuedThreads()879   public boolean hasQueuedThreads() {
880     return lock.hasQueuedThreads();
881   }
882 
883   /**
884    * Queries whether the given thread is waiting to enter this monitor. Note that because
885    * cancellations may occur at any time, a {@code true} return does not guarantee that this thread
886    * will ever enter this monitor. This method is designed primarily for use in monitoring of the
887    * system state.
888    */
hasQueuedThread(Thread thread)889   public boolean hasQueuedThread(Thread thread) {
890     return lock.hasQueuedThread(thread);
891   }
892 
893   /**
894    * Queries whether any threads are waiting for the given guard to become satisfied. Note that
895    * because timeouts and interrupts may occur at any time, a {@code true} return does not guarantee
896    * that the guard becoming satisfied in the future will awaken any threads. This method is
897    * designed primarily for use in monitoring of the system state.
898    */
hasWaiters(Guard guard)899   public boolean hasWaiters(Guard guard) {
900     return getWaitQueueLength(guard) > 0;
901   }
902 
903   /**
904    * Returns an estimate of the number of threads waiting for the given guard to become satisfied.
905    * Note that because timeouts and interrupts may occur at any time, the estimate serves only as an
906    * upper bound on the actual number of waiters. This method is designed for use in monitoring of
907    * the system state, not for synchronization control.
908    */
getWaitQueueLength(Guard guard)909   public int getWaitQueueLength(Guard guard) {
910     if (guard.monitor != this) {
911       throw new IllegalMonitorStateException();
912     }
913     lock.lock();
914     try {
915       return guard.waiterCount;
916     } finally {
917       lock.unlock();
918     }
919   }
920 
921   /**
922    * Returns unit.toNanos(time), additionally ensuring the returned value is not at risk of
923    * overflowing or underflowing, by bounding the value between 0 and (Long.MAX_VALUE / 4) * 3.
924    * Actually waiting for more than 219 years is not supported!
925    */
toSafeNanos(long time, TimeUnit unit)926   private static long toSafeNanos(long time, TimeUnit unit) {
927     long timeoutNanos = unit.toNanos(time);
928     return Longs.constrainToRange(timeoutNanos, 0L, (Long.MAX_VALUE / 4) * 3);
929   }
930 
931   /**
932    * Returns System.nanoTime() unless the timeout has already elapsed. Returns 0L if and only if the
933    * timeout has already elapsed.
934    */
initNanoTime(long timeoutNanos)935   private static long initNanoTime(long timeoutNanos) {
936     if (timeoutNanos <= 0L) {
937       return 0L;
938     } else {
939       long startTime = System.nanoTime();
940       return (startTime == 0L) ? 1L : startTime;
941     }
942   }
943 
944   /**
945    * Returns the remaining nanos until the given timeout, or 0L if the timeout has already elapsed.
946    * Caller must have previously sanitized timeoutNanos using toSafeNanos.
947    */
remainingNanos(long startTime, long timeoutNanos)948   private static long remainingNanos(long startTime, long timeoutNanos) {
949     // assert timeoutNanos == 0L || startTime != 0L;
950 
951     // TODO : NOT CORRECT, BUT TESTS PASS ANYWAYS!
952     // if (true) return timeoutNanos;
953     // ONLY 2 TESTS FAIL IF WE DO:
954     // if (true) return 0;
955 
956     return (timeoutNanos <= 0L) ? 0L : timeoutNanos - (System.nanoTime() - startTime);
957   }
958 
959   /**
960    * Signals some other thread waiting on a satisfied guard, if one exists.
961    *
962    * <p>We manage calls to this method carefully, to signal only when necessary, but never losing a
963    * signal, which is the classic problem of this kind of concurrency construct. We must signal if
964    * the current thread is about to relinquish the lock and may have changed the state protected by
965    * the monitor, thereby causing some guard to be satisfied.
966    *
967    * <p>In addition, any thread that has been signalled when its guard was satisfied acquires the
968    * responsibility of signalling the next thread when it again relinquishes the lock. Unlike a
969    * normal Condition, there is no guarantee that an interrupted thread has not been signalled,
970    * since the concurrency control must manage multiple Conditions. So this method must generally be
971    * called when waits are interrupted.
972    *
973    * <p>On the other hand, if a signalled thread wakes up to discover that its guard is still not
974    * satisfied, it does *not* need to call this method before returning to wait. This can only
975    * happen due to spurious wakeup (ignorable) or another thread acquiring the lock before the
976    * current thread can and returning the guard to the unsatisfied state. In the latter case the
977    * other thread (last thread modifying the state protected by the monitor) takes over the
978    * responsibility of signalling the next waiter.
979    *
980    * <p>This method must not be called from within a beginWaitingFor/endWaitingFor block, or else
981    * the current thread's guard might be mistakenly signalled, leading to a lost signal.
982    */
983   @GuardedBy("lock")
signalNextWaiter()984   private void signalNextWaiter() {
985     for (Guard guard = activeGuards; guard != null; guard = guard.next) {
986       if (isSatisfied(guard)) {
987         guard.condition.signal();
988         break;
989       }
990     }
991   }
992 
993   /**
994    * Exactly like signalNextWaiter, but caller guarantees that guardToSkip need not be considered,
995    * because caller has previously checked that guardToSkip.isSatisfied() returned false. An
996    * optimization for the case that guardToSkip.isSatisfied() may be expensive.
997    *
998    * <p>We decided against using this method, since in practice, isSatisfied() is likely to be very
999    * cheap (typically one field read). Resurrect this method if you find that not to be true.
1000    */
1001   //   @GuardedBy("lock")
1002   //   private void signalNextWaiterSkipping(Guard guardToSkip) {
1003   //     for (Guard guard = activeGuards; guard != null; guard = guard.next) {
1004   //       if (guard != guardToSkip && isSatisfied(guard)) {
1005   //         guard.condition.signal();
1006   //         break;
1007   //       }
1008   //     }
1009   //   }
1010 
1011   /**
1012    * Exactly like guard.isSatisfied(), but in addition signals all waiting threads in the (hopefully
1013    * unlikely) event that isSatisfied() throws.
1014    */
1015   @GuardedBy("lock")
isSatisfied(Guard guard)1016   private boolean isSatisfied(Guard guard) {
1017     try {
1018       return guard.isSatisfied();
1019     } catch (Throwable throwable) {
1020       // Any Exception is either a RuntimeException or sneaky checked exception.
1021       signalAllWaiters();
1022       throw throwable;
1023     }
1024   }
1025 
1026   /** Signals all threads waiting on guards. */
1027   @GuardedBy("lock")
signalAllWaiters()1028   private void signalAllWaiters() {
1029     for (Guard guard = activeGuards; guard != null; guard = guard.next) {
1030       guard.condition.signalAll();
1031     }
1032   }
1033 
1034   /** Records that the current thread is about to wait on the specified guard. */
1035   @GuardedBy("lock")
beginWaitingFor(Guard guard)1036   private void beginWaitingFor(Guard guard) {
1037     int waiters = guard.waiterCount++;
1038     if (waiters == 0) {
1039       // push guard onto activeGuards
1040       guard.next = activeGuards;
1041       activeGuards = guard;
1042     }
1043   }
1044 
1045   /** Records that the current thread is no longer waiting on the specified guard. */
1046   @GuardedBy("lock")
endWaitingFor(Guard guard)1047   private void endWaitingFor(Guard guard) {
1048     int waiters = --guard.waiterCount;
1049     if (waiters == 0) {
1050       // unlink guard from activeGuards
1051       for (Guard p = activeGuards, pred = null; ; pred = p, p = p.next) {
1052         if (p == guard) {
1053           if (pred == null) {
1054             activeGuards = p.next;
1055           } else {
1056             pred.next = p.next;
1057           }
1058           p.next = null; // help GC
1059           break;
1060         }
1061       }
1062     }
1063   }
1064 
1065   /*
1066    * Methods that loop waiting on a guard's condition until the guard is satisfied, while recording
1067    * this fact so that other threads know to check our guard and signal us. It's caller's
1068    * responsibility to ensure that the guard is *not* currently satisfied.
1069    */
1070 
1071   @GuardedBy("lock")
await(Guard guard, boolean signalBeforeWaiting)1072   private void await(Guard guard, boolean signalBeforeWaiting) throws InterruptedException {
1073     if (signalBeforeWaiting) {
1074       signalNextWaiter();
1075     }
1076     beginWaitingFor(guard);
1077     try {
1078       do {
1079         guard.condition.await();
1080       } while (!guard.isSatisfied());
1081     } finally {
1082       endWaitingFor(guard);
1083     }
1084   }
1085 
1086   @GuardedBy("lock")
awaitUninterruptibly(Guard guard, boolean signalBeforeWaiting)1087   private void awaitUninterruptibly(Guard guard, boolean signalBeforeWaiting) {
1088     if (signalBeforeWaiting) {
1089       signalNextWaiter();
1090     }
1091     beginWaitingFor(guard);
1092     try {
1093       do {
1094         guard.condition.awaitUninterruptibly();
1095       } while (!guard.isSatisfied());
1096     } finally {
1097       endWaitingFor(guard);
1098     }
1099   }
1100 
1101   /** Caller should check before calling that guard is not satisfied. */
1102   @GuardedBy("lock")
awaitNanos(Guard guard, long nanos, boolean signalBeforeWaiting)1103   private boolean awaitNanos(Guard guard, long nanos, boolean signalBeforeWaiting)
1104       throws InterruptedException {
1105     boolean firstTime = true;
1106     try {
1107       do {
1108         if (nanos <= 0L) {
1109           return false;
1110         }
1111         if (firstTime) {
1112           if (signalBeforeWaiting) {
1113             signalNextWaiter();
1114           }
1115           beginWaitingFor(guard);
1116           firstTime = false;
1117         }
1118         nanos = guard.condition.awaitNanos(nanos);
1119       } while (!guard.isSatisfied());
1120       return true;
1121     } finally {
1122       if (!firstTime) {
1123         endWaitingFor(guard);
1124       }
1125     }
1126   }
1127 }
1128