11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2010 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.util.concurrent;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Throwables;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.TimeUnit;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.locks.Condition;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.locks.ReentrantLock;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.concurrent.GuardedBy;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A synchronization abstraction supporting waiting on arbitrary boolean conditions.
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This class is intended as a replacement for {@link ReentrantLock}. Code using {@code Monitor}
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is less error-prone and more readable than code using {@code ReentrantLock}, without significant
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * performance loss. {@code Monitor} even has the potential for performance gain by optimizing the
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * evaluation and signaling of conditions.  Signaling is entirely
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <a href="http://en.wikipedia.org/wiki/Monitor_(synchronization)#Implicit_signaling">
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * implicit</a>.
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * By eliminating explicit signaling, this class can guarantee that only one thread is awakened
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * when a condition becomes true (no "signaling storms" due to use of {@link
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * java.util.concurrent.locks.Condition#signalAll Condition.signalAll}) and that no signals are lost
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * (no "hangs" due to incorrect use of {@link java.util.concurrent.locks.Condition#signal
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Condition.signal}).
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>A thread is said to <i>occupy</i> a monitor if it has <i>entered</i> the monitor but not yet
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <i>left</i>. Only one thread may occupy a given monitor at any moment. A monitor is also
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * reentrant, so a thread may enter a monitor any number of times, and then must leave the same
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * number of times. The <i>enter</i> and <i>leave</i> operations have the same synchronization
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * semantics as the built-in Java language synchronization primitives.
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>A call to any of the <i>enter</i> methods with <b>void</b> return type should always be
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * followed immediately by a <i>try/finally</i> block to ensure that the current thread leaves the
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * monitor cleanly: <pre>   {@code
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   monitor.enter();
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   try {
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     // do things while occupying the monitor
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   } finally {
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     monitor.leave();
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   }}</pre>
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
620888a09821a98ac0680fad765217302858e70fa4Paul Duffin * <p>A call to any of the <i>enter</i> methods with <b>boolean</b> return type should always
630888a09821a98ac0680fad765217302858e70fa4Paul Duffin * appear as the condition of an <i>if</i> statement containing a <i>try/finally</i> block to
640888a09821a98ac0680fad765217302858e70fa4Paul Duffin * ensure that the current thread leaves the monitor cleanly: <pre>   {@code
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   if (monitor.tryEnter()) {
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     try {
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       // do things while occupying the monitor
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     } finally {
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       monitor.leave();
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     }
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   } else {
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     // do other things since the monitor was not available
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   }}</pre>
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <h2>Comparison with {@code synchronized} and {@code ReentrantLock}</h2>
770888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The following examples show a simple threadsafe holder expressed using {@code synchronized},
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link ReentrantLock}, and {@code Monitor}.
800888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <h3>{@code synchronized}</h3>
820888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This version is the fewest lines of code, largely because the synchronization mechanism used
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is built into the language and runtime. But the programmer has to remember to avoid a couple of
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * common bugs: The {@code wait()} must be inside a {@code while} instead of an {@code if}, and
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code notifyAll()} must be used instead of {@code notify()} because there are two different
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * logical conditions being awaited. <pre>   {@code
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   public class SafeBox<V> {
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     private V value;
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     public synchronized V get() throws InterruptedException {
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       while (value == null) {
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         wait();
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       }
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       V result = value;
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       value = null;
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       notifyAll();
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       return result;
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     }
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     public synchronized void set(V newValue) throws InterruptedException {
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       while (value != null) {
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         wait();
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       }
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       value = newValue;
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       notifyAll();
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     }
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   }}</pre>
1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <h3>{@code ReentrantLock}</h3>
1120888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This version is much more verbose than the {@code synchronized} version, and still suffers
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * from the need for the programmer to remember to use {@code while} instead of {@code if}.
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * However, one advantage is that we can introduce two separate {@code Condition} objects, which
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allows us to use {@code signal()} instead of {@code signalAll()}, which may be a performance
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * benefit. <pre>   {@code
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   public class SafeBox<V> {
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     private final ReentrantLock lock = new ReentrantLock();
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     private final Condition valuePresent = lock.newCondition();
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     private final Condition valueAbsent = lock.newCondition();
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     private V value;
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     public V get() throws InterruptedException {
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       lock.lock();
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       try {
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         while (value == null) {
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *           valuePresent.await();
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         }
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         V result = value;
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         value = null;
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         valueAbsent.signal();
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         return result;
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       } finally {
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         lock.unlock();
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       }
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     }
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     public void set(V newValue) throws InterruptedException {
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       lock.lock();
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       try {
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         while (value != null) {
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *           valueAbsent.await();
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         }
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         value = newValue;
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         valuePresent.signal();
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       } finally {
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         lock.unlock();
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       }
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     }
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   }}</pre>
1530888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <h3>{@code Monitor}</h3>
1550888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This version adds some verbosity around the {@code Guard} objects, but removes that same
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * verbosity, and more, from the {@code get} and {@code set} methods. {@code Monitor} implements the
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * same efficient signaling as we had to hand-code in the {@code ReentrantLock} version above.
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Finally, the programmer no longer has to hand-code the wait loop, and therefore doesn't have to
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * remember to use {@code while} instead of {@code if}. <pre>   {@code
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   public class SafeBox<V> {
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     private final Monitor monitor = new Monitor();
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     private final Monitor.Guard valuePresent = new Monitor.Guard(monitor) {
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       public boolean isSatisfied() {
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         return value != null;
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       }
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     };
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     private final Monitor.Guard valueAbsent = new Monitor.Guard(monitor) {
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       public boolean isSatisfied() {
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         return value == null;
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       }
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     };
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     private V value;
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     public V get() throws InterruptedException {
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       monitor.enterWhen(valuePresent);
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       try {
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         V result = value;
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         value = null;
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         return result;
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       } finally {
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         monitor.leave();
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       }
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     }
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     public void set(V newValue) throws InterruptedException {
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       monitor.enterWhen(valueAbsent);
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       try {
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         value = newValue;
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       } finally {
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *         monitor.leave();
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *       }
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *     }
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   }}</pre>
1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Justin T. Sampson
1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @author Martin Buchholz
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class Monitor {
2030888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // TODO(user): Use raw LockSupport or AbstractQueuedSynchronizer instead of ReentrantLock.
2040888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // TODO(user): "Port" jsr166 tests for ReentrantLock.
2050888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //
2060888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // TODO(user): Change API to make it impossible to use a Guard with the "wrong" monitor,
2070888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    by making the monitor implicit, and to eliminate other sources of IMSE.
2080888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    Imagine:
2090888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    guard.lock();
2100888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    try { /* monitor locked and guard satisfied here */ }
2110888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    finally { guard.unlock(); }
2120888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // Here are Justin's design notes about this:
2130888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //
2140888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // This idea has come up from time to time, and I think one of my
2150888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // earlier versions of Monitor even did something like this. I ended
2160888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // up strongly favoring the current interface.
2170888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //
2180888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // I probably can't remember all the reasons (it's possible you
2190888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // could find them in the code review archives), but here are a few:
2200888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //
2210888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // 1. What about leaving/unlocking? Are you going to do
2220888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    guard.enter() paired with monitor.leave()? That might get
2230888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    confusing. It's nice for the finally block to look as close as
2240888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    possible to the thing right before the try. You could have
2250888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    guard.leave(), but that's a little odd as well because the
2260888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    guard doesn't have anything to do with leaving. You can't
2270888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    really enforce that the guard you're leaving is the same one
2280888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    you entered with, and it doesn't actually matter.
2290888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //
2300888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // 2. Since you can enter the monitor without a guard at all, some
2310888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    places you'll have monitor.enter()/monitor.leave() and other
2320888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    places you'll have guard.enter()/guard.leave() even though
2330888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    it's the same lock being acquired underneath. Always using
2340888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    monitor.enterXXX()/monitor.leave() will make it really clear
2350888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    which lock is held at any point in the code.
2360888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //
2370888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // 3. I think "enterWhen(notEmpty)" reads better than "notEmpty.enter()".
2380888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //
2390888a09821a98ac0680fad765217302858e70fa4Paul Duffin  // TODO(user): Implement ReentrantLock features:
2400888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    - toString() method
2410888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    - getOwner() method
2420888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    - getQueuedThreads() method
2430888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    - getWaitingThreads(Guard) method
2440888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    - implement Serializable
2450888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //    - redo the API to be as close to identical to ReentrantLock as possible,
2460888a09821a98ac0680fad765217302858e70fa4Paul Duffin  //      since, after all, this class is also a reentrant mutual exclusion lock!?
2470888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2480888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /*
2490888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * One of the key challenges of this class is to prevent lost signals, while trying hard to
2500888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * minimize unnecessary signals.  One simple and correct algorithm is to signal some other
2510888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * waiter with a satisfied guard (if one exists) whenever any thread occupying the monitor
2520888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * exits the monitor, either by unlocking all of its held locks, or by starting to wait for a
2530888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * guard.  This includes exceptional exits, so all control paths involving signalling must be
2540888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * protected by a finally block.
2550888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
2560888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Further optimizations of this algorithm become increasingly subtle.  A wait that terminates
2570888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * without the guard being satisfied (due to timeout, but not interrupt) can then immediately
2580888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * exit the monitor without signalling.  If it timed out without being signalled, it does not
2590888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * need to "pass on" the signal to another thread.  If it *was* signalled, then its guard must
2600888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * have been satisfied at the time of signal, and has since been modified by some other thread
2610888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * to be non-satisfied before reacquiring the lock, and that other thread takes over the
2620888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * responsibility of signaling the next waiter.
2630888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
2640888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Unlike the underlying Condition, if we are not careful, an interrupt *can* cause a signal to
2650888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * be lost, because the signal may be sent to a condition whose sole waiter has just been
2660888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * interrupted.
2670888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
2680888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Imagine a monitor with multiple guards.  A thread enters the monitor, satisfies all the
2690888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * guards, and leaves, calling signalNextWaiter.  With traditional locks and conditions, all
2700888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * the conditions need to be signalled because it is not known which if any of them have
2710888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * waiters (and hasWaiters can't be used reliably because of a check-then-act race).  With our
2720888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Monitor guards, we only signal the first active guard that is satisfied.  But the
2730888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * corresponding thread may have already been interrupted and is waiting to reacquire the lock
2740888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * while still registered in activeGuards, in which case the signal is a no-op, and the
2750888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * bigger-picture signal is lost unless interrupted threads take special action by
2760888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * participating in the signal-passing game.
2770888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * A boolean condition for which a thread may wait. A {@code Guard} is associated with a single
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code Monitor}. The monitor may check the guard at arbitrary times from any thread occupying
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the monitor, so code should not be written to rely on how often a guard might or might not be
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * checked.
2840888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>If a {@code Guard} is passed into any method of a {@code Monitor} other than the one it is
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * associated with, an {@link IllegalMonitorStateException} is thrown.
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Beta
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public abstract static class Guard {
2927dd252788645e940eada959bdde927426e2531c9Paul Duffin
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Monitor monitor;
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Condition condition;
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @GuardedBy("monitor.lock")
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int waiterCount = 0;
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2990888a09821a98ac0680fad765217302858e70fa4Paul Duffin    /** The next active guard */
3000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @GuardedBy("monitor.lock")
3010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Guard next;
3020888a09821a98ac0680fad765217302858e70fa4Paul Duffin
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    protected Guard(Monitor monitor) {
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.monitor = checkNotNull(monitor, "monitor");
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.condition = monitor.lock.newCondition();
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Evaluates this guard's boolean condition. This method is always called with the associated
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * monitor already occupied. Implementations of this method must depend only on state protected
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * by the associated monitor, and must not modify that state.
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public abstract boolean isSatisfied();
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Whether this monitor is fair.
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private final boolean fair;
3217dd252788645e940eada959bdde927426e2531c9Paul Duffin
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * The lock underlying this monitor.
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private final ReentrantLock lock;
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * The guards associated with this monitor that currently have waiters ({@code waiterCount > 0}).
3290888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * A linked list threaded through the Guard.next field.
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GuardedBy("lock")
3320888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private Guard activeGuards = null;
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a monitor with a non-fair (but fast) ordering policy. Equivalent to {@code
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Monitor(false)}.
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public Monitor() {
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    this(false);
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a monitor with the given ordering policy.
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param fair whether this monitor should use a fair ordering policy rather than a non-fair (but
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *        fast) one
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public Monitor(boolean fair) {
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    this.fair = fair;
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    this.lock = new ReentrantLock(fair);
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor. Blocks indefinitely.
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void enter() {
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    lock.lock();
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor. Blocks indefinitely, but may be interrupted.
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void enterInterruptibly() throws InterruptedException {
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    lock.lockInterruptibly();
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor. Blocks at most the given time.
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return whether the monitor was entered
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean enter(long time, TimeUnit unit) {
3730888a09821a98ac0680fad765217302858e70fa4Paul Duffin    long timeoutNanos = unit.toNanos(time);
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final ReentrantLock lock = this.lock;
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (!fair && lock.tryLock()) {
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return true;
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    long deadline = System.nanoTime() + timeoutNanos;
3790888a09821a98ac0680fad765217302858e70fa4Paul Duffin    boolean interrupted = Thread.interrupted();
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      while (true) {
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        try {
3830888a09821a98ac0680fad765217302858e70fa4Paul Duffin          return lock.tryLock(timeoutNanos, TimeUnit.NANOSECONDS);
3840888a09821a98ac0680fad765217302858e70fa4Paul Duffin        } catch (InterruptedException interrupt) {
3850888a09821a98ac0680fad765217302858e70fa4Paul Duffin          interrupted = true;
3860888a09821a98ac0680fad765217302858e70fa4Paul Duffin          timeoutNanos = deadline - System.nanoTime();
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
3900888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (interrupted) {
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Thread.currentThread().interrupt();
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor. Blocks at most the given time, and may be interrupted.
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return whether the monitor was entered
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean enterInterruptibly(long time, TimeUnit unit) throws InterruptedException {
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return lock.tryLock(time, unit);
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor if it is possible to do so immediately. Does not block.
4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p><b>Note:</b> This method disregards the fairness setting of this monitor.
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return whether the monitor was entered
4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean tryEnter() {
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return lock.tryLock();
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor when the guard is satisfied. Blocks indefinitely, but may be interrupted.
4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void enterWhen(Guard guard) throws InterruptedException {
4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (guard.monitor != this) {
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final ReentrantLock lock = this.lock;
4240888a09821a98ac0680fad765217302858e70fa4Paul Duffin    boolean signalBeforeWaiting = lock.isHeldByCurrentThread();
4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    lock.lockInterruptibly();
4260888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    boolean satisfied = false;
4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
4290888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (!guard.isSatisfied()) {
4300888a09821a98ac0680fad765217302858e70fa4Paul Duffin        await(guard, signalBeforeWaiting);
4310888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
4320888a09821a98ac0680fad765217302858e70fa4Paul Duffin      satisfied = true;
4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
4340888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (!satisfied) {
4350888a09821a98ac0680fad765217302858e70fa4Paul Duffin        leave();
4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor when the guard is satisfied. Blocks indefinitely.
4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void enterWhenUninterruptibly(Guard guard) {
4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (guard.monitor != this) {
4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final ReentrantLock lock = this.lock;
4480888a09821a98ac0680fad765217302858e70fa4Paul Duffin    boolean signalBeforeWaiting = lock.isHeldByCurrentThread();
4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    lock.lock();
4500888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    boolean satisfied = false;
4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
4530888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (!guard.isSatisfied()) {
4540888a09821a98ac0680fad765217302858e70fa4Paul Duffin        awaitUninterruptibly(guard, signalBeforeWaiting);
4550888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
4560888a09821a98ac0680fad765217302858e70fa4Paul Duffin      satisfied = true;
4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
4580888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (!satisfied) {
4590888a09821a98ac0680fad765217302858e70fa4Paul Duffin        leave();
4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor when the guard is satisfied. Blocks at most the given time, including both
4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the time to acquire the lock and the time to wait for the guard to be satisfied, and may be
4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * interrupted.
4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
4690888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @return whether the monitor was entered with the guard satisfied
4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean enterWhen(Guard guard, long time, TimeUnit unit) throws InterruptedException {
4720888a09821a98ac0680fad765217302858e70fa4Paul Duffin    long timeoutNanos = unit.toNanos(time);
4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (guard.monitor != this) {
4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final ReentrantLock lock = this.lock;
4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean reentrant = lock.isHeldByCurrentThread();
4780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (fair || !lock.tryLock()) {
4790888a09821a98ac0680fad765217302858e70fa4Paul Duffin      long deadline = System.nanoTime() + timeoutNanos;
4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!lock.tryLock(time, unit)) {
4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4830888a09821a98ac0680fad765217302858e70fa4Paul Duffin      timeoutNanos = deadline - System.nanoTime();
4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4850888a09821a98ac0680fad765217302858e70fa4Paul Duffin
4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean satisfied = false;
4870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    boolean threw = true;
4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
4890888a09821a98ac0680fad765217302858e70fa4Paul Duffin      satisfied = guard.isSatisfied() || awaitNanos(guard, timeoutNanos, reentrant);
4900888a09821a98ac0680fad765217302858e70fa4Paul Duffin      threw = false;
4910888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return satisfied;
4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!satisfied) {
4940888a09821a98ac0680fad765217302858e70fa4Paul Duffin        try {
4950888a09821a98ac0680fad765217302858e70fa4Paul Duffin          // Don't need to signal if timed out, but do if interrupted
4960888a09821a98ac0680fad765217302858e70fa4Paul Duffin          if (threw && !reentrant) {
4970888a09821a98ac0680fad765217302858e70fa4Paul Duffin            signalNextWaiter();
4980888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
4990888a09821a98ac0680fad765217302858e70fa4Paul Duffin        } finally {
5000888a09821a98ac0680fad765217302858e70fa4Paul Duffin          lock.unlock();
5010888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor when the guard is satisfied. Blocks at most the given time, including
5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * both the time to acquire the lock and the time to wait for the guard to be satisfied.
5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
5100888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @return whether the monitor was entered with the guard satisfied
5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean enterWhenUninterruptibly(Guard guard, long time, TimeUnit unit) {
5130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    long timeoutNanos = unit.toNanos(time);
5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (guard.monitor != this) {
5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final ReentrantLock lock = this.lock;
5180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    long deadline = System.nanoTime() + timeoutNanos;
5190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    boolean signalBeforeWaiting = lock.isHeldByCurrentThread();
5200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    boolean interrupted = Thread.interrupted();
5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5220888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (fair || !lock.tryLock()) {
5230888a09821a98ac0680fad765217302858e70fa4Paul Duffin        boolean locked = false;
5240888a09821a98ac0680fad765217302858e70fa4Paul Duffin        do {
5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          try {
5260888a09821a98ac0680fad765217302858e70fa4Paul Duffin            locked = lock.tryLock(timeoutNanos, TimeUnit.NANOSECONDS);
5270888a09821a98ac0680fad765217302858e70fa4Paul Duffin            if (!locked) {
5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return false;
5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
5300888a09821a98ac0680fad765217302858e70fa4Paul Duffin          } catch (InterruptedException interrupt) {
5310888a09821a98ac0680fad765217302858e70fa4Paul Duffin            interrupted = true;
5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
5330888a09821a98ac0680fad765217302858e70fa4Paul Duffin          timeoutNanos = deadline - System.nanoTime();
5340888a09821a98ac0680fad765217302858e70fa4Paul Duffin        } while (!locked);
5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5360888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean satisfied = false;
5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
5390888a09821a98ac0680fad765217302858e70fa4Paul Duffin        while (true) {
5400888a09821a98ac0680fad765217302858e70fa4Paul Duffin          try {
5410888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return satisfied = guard.isSatisfied()
5420888a09821a98ac0680fad765217302858e70fa4Paul Duffin                || awaitNanos(guard, timeoutNanos, signalBeforeWaiting);
5430888a09821a98ac0680fad765217302858e70fa4Paul Duffin          } catch (InterruptedException interrupt) {
5440888a09821a98ac0680fad765217302858e70fa4Paul Duffin            interrupted = true;
5450888a09821a98ac0680fad765217302858e70fa4Paul Duffin            signalBeforeWaiting = false;
5460888a09821a98ac0680fad765217302858e70fa4Paul Duffin            timeoutNanos = deadline - System.nanoTime();
5470888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
5480888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } finally {
5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (!satisfied) {
5510888a09821a98ac0680fad765217302858e70fa4Paul Duffin          lock.unlock();  // No need to signal if timed out
5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
5550888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (interrupted) {
5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Thread.currentThread().interrupt();
5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor if the guard is satisfied. Blocks indefinitely acquiring the lock, but
5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * does not wait for the guard to be satisfied.
5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
5650888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @return whether the monitor was entered with the guard satisfied
5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean enterIf(Guard guard) {
5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (guard.monitor != this) {
5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final ReentrantLock lock = this.lock;
5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    lock.lock();
5730888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean satisfied = false;
5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5760888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return satisfied = guard.isSatisfied();
5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!satisfied) {
5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        lock.unlock();
5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor if the guard is satisfied. Blocks indefinitely acquiring the lock, but does
5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * not wait for the guard to be satisfied, and may be interrupted.
5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
5880888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @return whether the monitor was entered with the guard satisfied
5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean enterIfInterruptibly(Guard guard) throws InterruptedException {
5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (guard.monitor != this) {
5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final ReentrantLock lock = this.lock;
5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    lock.lockInterruptibly();
5960888a09821a98ac0680fad765217302858e70fa4Paul Duffin
5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean satisfied = false;
5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
5990888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return satisfied = guard.isSatisfied();
6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!satisfied) {
6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        lock.unlock();
6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor if the guard is satisfied. Blocks at most the given time acquiring the
6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * lock, but does not wait for the guard to be satisfied.
6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
6110888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @return whether the monitor was entered with the guard satisfied
6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean enterIf(Guard guard, long time, TimeUnit unit) {
6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (guard.monitor != this) {
6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (!enter(time, unit)) {
6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6200888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean satisfied = false;
6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
6230888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return satisfied = guard.isSatisfied();
6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!satisfied) {
6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        lock.unlock();
6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor if the guard is satisfied. Blocks at most the given time acquiring the
6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * lock, but does not wait for the guard to be satisfied, and may be interrupted.
6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
6350888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @return whether the monitor was entered with the guard satisfied
6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean enterIfInterruptibly(Guard guard, long time, TimeUnit unit)
6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throws InterruptedException {
6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (guard.monitor != this) {
6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final ReentrantLock lock = this.lock;
6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (!lock.tryLock(time, unit)) {
6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6460888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean satisfied = false;
6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
6490888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return satisfied = guard.isSatisfied();
6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!satisfied) {
6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        lock.unlock();
6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Enters this monitor if it is possible to do so immediately and the guard is satisfied. Does not
6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * block acquiring the lock and does not wait for the guard to be satisfied.
6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p><b>Note:</b> This method disregards the fairness setting of this monitor.
6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
6630888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @return whether the monitor was entered with the guard satisfied
6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean tryEnterIf(Guard guard) {
6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (guard.monitor != this) {
6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final ReentrantLock lock = this.lock;
6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (!lock.tryLock()) {
6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6730888a09821a98ac0680fad765217302858e70fa4Paul Duffin
6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean satisfied = false;
6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
6760888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return satisfied = guard.isSatisfied();
6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!satisfied) {
6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        lock.unlock();
6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Waits for the guard to be satisfied. Waits indefinitely, but may be interrupted. May be
6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * called only by a thread currently occupying this monitor.
6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void waitFor(Guard guard) throws InterruptedException {
6890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (!((guard.monitor == this) & lock.isHeldByCurrentThread())) {
6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (!guard.isSatisfied()) {
6930888a09821a98ac0680fad765217302858e70fa4Paul Duffin      await(guard, true);
6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Waits for the guard to be satisfied. Waits indefinitely. May be called only by a thread
6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * currently occupying this monitor.
7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void waitForUninterruptibly(Guard guard) {
7020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (!((guard.monitor == this) & lock.isHeldByCurrentThread())) {
7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (!guard.isSatisfied()) {
7060888a09821a98ac0680fad765217302858e70fa4Paul Duffin      awaitUninterruptibly(guard, true);
7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Waits for the guard to be satisfied. Waits at most the given time, and may be interrupted.
7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * May be called only by a thread currently occupying this monitor.
7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return whether the guard is now satisfied
7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean waitFor(Guard guard, long time, TimeUnit unit) throws InterruptedException {
7170888a09821a98ac0680fad765217302858e70fa4Paul Duffin    long timeoutNanos = unit.toNanos(time);
7180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (!((guard.monitor == this) & lock.isHeldByCurrentThread())) {
7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return guard.isSatisfied() || awaitNanos(guard, timeoutNanos, true);
7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Waits for the guard to be satisfied. Waits at most the given time. May be called only by a
7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * thread currently occupying this monitor.
7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return whether the guard is now satisfied
7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean waitForUninterruptibly(Guard guard, long time, TimeUnit unit) {
7310888a09821a98ac0680fad765217302858e70fa4Paul Duffin    long timeoutNanos = unit.toNanos(time);
7320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (!((guard.monitor == this) & lock.isHeldByCurrentThread())) {
7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7350888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (guard.isSatisfied()) {
7360888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return true;
7370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
7380888a09821a98ac0680fad765217302858e70fa4Paul Duffin    boolean signalBeforeWaiting = true;
7390888a09821a98ac0680fad765217302858e70fa4Paul Duffin    long deadline = System.nanoTime() + timeoutNanos;
7400888a09821a98ac0680fad765217302858e70fa4Paul Duffin    boolean interrupted = Thread.interrupted();
7410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
7420888a09821a98ac0680fad765217302858e70fa4Paul Duffin      while (true) {
7430888a09821a98ac0680fad765217302858e70fa4Paul Duffin        try {
7440888a09821a98ac0680fad765217302858e70fa4Paul Duffin          return awaitNanos(guard, timeoutNanos, signalBeforeWaiting);
7450888a09821a98ac0680fad765217302858e70fa4Paul Duffin        } catch (InterruptedException interrupt) {
7460888a09821a98ac0680fad765217302858e70fa4Paul Duffin          interrupted = true;
7470888a09821a98ac0680fad765217302858e70fa4Paul Duffin          if (guard.isSatisfied()) {
7480888a09821a98ac0680fad765217302858e70fa4Paul Duffin            return true;
7490888a09821a98ac0680fad765217302858e70fa4Paul Duffin          }
7500888a09821a98ac0680fad765217302858e70fa4Paul Duffin          signalBeforeWaiting = false;
7510888a09821a98ac0680fad765217302858e70fa4Paul Duffin          timeoutNanos = deadline - System.nanoTime();
7520888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
7530888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
7540888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } finally {
7550888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (interrupted) {
7560888a09821a98ac0680fad765217302858e70fa4Paul Duffin        Thread.currentThread().interrupt();
7570888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Leaves this monitor. May be called only by a thread currently occupying this monitor.
7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void leave() {
7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final ReentrantLock lock = this.lock;
7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
7670888a09821a98ac0680fad765217302858e70fa4Paul Duffin      // No need to signal if we will still be holding the lock when we return
7680888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (lock.getHoldCount() == 1) {
7690888a09821a98ac0680fad765217302858e70fa4Paul Duffin        signalNextWaiter();
7700888a09821a98ac0680fad765217302858e70fa4Paul Duffin      }
7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
7720888a09821a98ac0680fad765217302858e70fa4Paul Duffin      lock.unlock();  // Will throw IllegalMonitorStateException if not held
7731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns whether this monitor is using a fair ordering policy.
7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean isFair() {
7800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return fair;
7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns whether this monitor is occupied by any thread. This method is designed for use in
7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * monitoring of the system state, not for synchronization control.
7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean isOccupied() {
7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return lock.isLocked();
7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns whether the current thread is occupying this monitor (has entered more times than it
7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * has left).
7941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean isOccupiedByCurrentThread() {
7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return lock.isHeldByCurrentThread();
7971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the number of times the current thread has entered this monitor in excess of the number
8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * of times it has left. Returns 0 if the current thread is not occupying this monitor.
8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public int getOccupiedDepth() {
8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return lock.getHoldCount();
8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an estimate of the number of threads waiting to enter this monitor. The value is only
8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * an estimate because the number of threads may change dynamically while this method traverses
8101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * internal data structures. This method is designed for use in monitoring of the system state,
8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * not for synchronization control.
8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public int getQueueLength() {
8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return lock.getQueueLength();
8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns whether any threads are waiting to enter this monitor. Note that because cancellations
8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * may occur at any time, a {@code true} return does not guarantee that any other thread will ever
8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * enter this monitor. This method is designed primarily for use in monitoring of the system
8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * state.
8221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean hasQueuedThreads() {
8241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return lock.hasQueuedThreads();
8251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Queries whether the given thread is waiting to enter this monitor. Note that because
8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * cancellations may occur at any time, a {@code true} return does not guarantee that this thread
8301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * will ever enter this monitor. This method is designed primarily for use in monitoring of the
8311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * system state.
8321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean hasQueuedThread(Thread thread) {
8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return lock.hasQueuedThread(thread);
8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Queries whether any threads are waiting for the given guard to become satisfied. Note that
8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * because timeouts and interrupts may occur at any time, a {@code true} return does not guarantee
8401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * that the guard becoming satisfied in the future will awaken any threads. This method is
8411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * designed primarily for use in monitoring of the system state.
8421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public boolean hasWaiters(Guard guard) {
8440888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return getWaitQueueLength(guard) > 0;
8451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
8481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an estimate of the number of threads waiting for the given guard to become satisfied.
8491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Note that because timeouts and interrupts may occur at any time, the estimate serves only as an
8501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * upper bound on the actual number of waiters. This method is designed for use in monitoring of
8511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the system state, not for synchronization control.
8521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
8531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public int getWaitQueueLength(Guard guard) {
8541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (guard.monitor != this) {
8551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalMonitorStateException();
8561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
8571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    lock.lock();
8581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
8591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return guard.waiterCount;
8601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } finally {
8611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      lock.unlock();
8621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
8631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
8641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
8650888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
8660888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Signals some other thread waiting on a satisfied guard, if one exists.
8670888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
8680888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * We manage calls to this method carefully, to signal only when necessary, but never losing a
8690888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * signal, which is the classic problem of this kind of concurrency construct.  We must signal if
8700888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * the current thread is about to relinquish the lock and may have changed the state protected by
8710888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * the monitor, thereby causing some guard to be satisfied.
8720888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
8730888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * In addition, any thread that has been signalled when its guard was satisfied acquires the
8740888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * responsibility of signalling the next thread when it again relinquishes the lock.  Unlike a
8750888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * normal Condition, there is no guarantee that an interrupted thread has not been signalled,
8760888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * since the concurrency control must manage multiple Conditions.  So this method must generally
8770888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * be called when waits are interrupted.
8780888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
8790888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * On the other hand, if a signalled thread wakes up to discover that its guard is still not
8800888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * satisfied, it does *not* need to call this method before returning to wait.  This can only
8810888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * happen due to spurious wakeup (ignorable) or another thread acquiring the lock before the
8820888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * current thread can and returning the guard to the unsatisfied state.  In the latter case the
8830888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * other thread (last thread modifying the state protected by the monitor) takes over the
8840888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * responsibility of signalling the next waiter.
8850888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
8860888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * This method must not be called from within a beginWaitingFor/endWaitingFor block, or else the
8870888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * current thread's guard might be mistakenly signalled, leading to a lost signal.
8880888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
8891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GuardedBy("lock")
8900888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void signalNextWaiter() {
8910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (Guard guard = activeGuards; guard != null; guard = guard.next) {
8920888a09821a98ac0680fad765217302858e70fa4Paul Duffin      if (isSatisfied(guard)) {
8930888a09821a98ac0680fad765217302858e70fa4Paul Duffin        guard.condition.signal();
8940888a09821a98ac0680fad765217302858e70fa4Paul Duffin        break;
8951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
8960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
8970888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
8980888a09821a98ac0680fad765217302858e70fa4Paul Duffin
8990888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
9000888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Exactly like signalNextWaiter, but caller guarantees that guardToSkip need not be considered,
9010888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * because caller has previously checked that guardToSkip.isSatisfied() returned false.
9020888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * An optimization for the case that guardToSkip.isSatisfied() may be expensive.
9030888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
9040888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * We decided against using this method, since in practice, isSatisfied() is likely to be very
9050888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * cheap (typically one field read).  Resurrect this method if you find that not to be true.
9060888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
9070888a09821a98ac0680fad765217302858e70fa4Paul Duffin//   @GuardedBy("lock")
9080888a09821a98ac0680fad765217302858e70fa4Paul Duffin//   private void signalNextWaiterSkipping(Guard guardToSkip) {
9090888a09821a98ac0680fad765217302858e70fa4Paul Duffin//     for (Guard guard = activeGuards; guard != null; guard = guard.next) {
9100888a09821a98ac0680fad765217302858e70fa4Paul Duffin//       if (guard != guardToSkip && isSatisfied(guard)) {
9110888a09821a98ac0680fad765217302858e70fa4Paul Duffin//         guard.condition.signal();
9120888a09821a98ac0680fad765217302858e70fa4Paul Duffin//         break;
9130888a09821a98ac0680fad765217302858e70fa4Paul Duffin//       }
9140888a09821a98ac0680fad765217302858e70fa4Paul Duffin//     }
9150888a09821a98ac0680fad765217302858e70fa4Paul Duffin//   }
9160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
9170888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
9180888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Exactly like guard.isSatisfied(), but in addition signals all waiting threads in the
9190888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * (hopefully unlikely) event that isSatisfied() throws.
9200888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
9210888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @GuardedBy("lock")
9220888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private boolean isSatisfied(Guard guard) {
9230888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
9240888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return guard.isSatisfied();
9251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (Throwable throwable) {
9260888a09821a98ac0680fad765217302858e70fa4Paul Duffin      signalAllWaiters();
9271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw Throwables.propagate(throwable);
9281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9307dd252788645e940eada959bdde927426e2531c9Paul Duffin
9310888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
9320888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Signals all threads waiting on guards.
9330888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
9341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GuardedBy("lock")
9350888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void signalAllWaiters() {
9360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    for (Guard guard = activeGuards; guard != null; guard = guard.next) {
9370888a09821a98ac0680fad765217302858e70fa4Paul Duffin      guard.condition.signalAll();
9381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9410888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
9420888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Records that the current thread is about to wait on the specified guard.
9430888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
9441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GuardedBy("lock")
9450888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void beginWaitingFor(Guard guard) {
9460888a09821a98ac0680fad765217302858e70fa4Paul Duffin    int waiters = guard.waiterCount++;
9471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (waiters == 0) {
9480888a09821a98ac0680fad765217302858e70fa4Paul Duffin      // push guard onto activeGuards
9490888a09821a98ac0680fad765217302858e70fa4Paul Duffin      guard.next = activeGuards;
9500888a09821a98ac0680fad765217302858e70fa4Paul Duffin      activeGuards = guard;
9511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9540888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
9550888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Records that the current thread is no longer waiting on the specified guard.
9560888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
9571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GuardedBy("lock")
9580888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void endWaitingFor(Guard guard) {
9590888a09821a98ac0680fad765217302858e70fa4Paul Duffin    int waiters = --guard.waiterCount;
9600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (waiters == 0) {
9610888a09821a98ac0680fad765217302858e70fa4Paul Duffin      // unlink guard from activeGuards
9620888a09821a98ac0680fad765217302858e70fa4Paul Duffin      for (Guard p = activeGuards, pred = null;; pred = p, p = p.next) {
9630888a09821a98ac0680fad765217302858e70fa4Paul Duffin        if (p == guard) {
9640888a09821a98ac0680fad765217302858e70fa4Paul Duffin          if (pred == null) {
9650888a09821a98ac0680fad765217302858e70fa4Paul Duffin            activeGuards = p.next;
9660888a09821a98ac0680fad765217302858e70fa4Paul Duffin          } else {
9670888a09821a98ac0680fad765217302858e70fa4Paul Duffin            pred.next = p.next;
9681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
9690888a09821a98ac0680fad765217302858e70fa4Paul Duffin          p.next = null;  // help GC
9700888a09821a98ac0680fad765217302858e70fa4Paul Duffin          break;
9710888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
9721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
9731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9760888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /*
9770888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Methods that loop waiting on a guard's condition until the guard is satisfied, while
9780888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * recording this fact so that other threads know to check our guard and signal us.
9790888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * It's caller's responsibility to ensure that the guard is *not* currently satisfied.
9800888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
9810888a09821a98ac0680fad765217302858e70fa4Paul Duffin
9821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GuardedBy("lock")
9830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private void await(Guard guard, boolean signalBeforeWaiting)
9840888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throws InterruptedException {
9850888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (signalBeforeWaiting) {
9860888a09821a98ac0680fad765217302858e70fa4Paul Duffin      signalNextWaiter();
9870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
9880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    beginWaitingFor(guard);
9890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
9900888a09821a98ac0680fad765217302858e70fa4Paul Duffin      do {
9910888a09821a98ac0680fad765217302858e70fa4Paul Duffin        guard.condition.await();
9920888a09821a98ac0680fad765217302858e70fa4Paul Duffin      } while (!guard.isSatisfied());
9930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } finally {
9940888a09821a98ac0680fad765217302858e70fa4Paul Duffin      endWaitingFor(guard);
9951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
9961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
9971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
9981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GuardedBy("lock")
9990888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private void awaitUninterruptibly(Guard guard, boolean signalBeforeWaiting) {
10000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (signalBeforeWaiting) {
10010888a09821a98ac0680fad765217302858e70fa4Paul Duffin      signalNextWaiter();
10020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
10030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    beginWaitingFor(guard);
10040888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
10050888a09821a98ac0680fad765217302858e70fa4Paul Duffin      do {
10060888a09821a98ac0680fad765217302858e70fa4Paul Duffin        guard.condition.awaitUninterruptibly();
10070888a09821a98ac0680fad765217302858e70fa4Paul Duffin      } while (!guard.isSatisfied());
10080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } finally {
10090888a09821a98ac0680fad765217302858e70fa4Paul Duffin      endWaitingFor(guard);
10101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @GuardedBy("lock")
10140888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private boolean awaitNanos(Guard guard, long nanos, boolean signalBeforeWaiting)
10150888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throws InterruptedException {
10160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    if (signalBeforeWaiting) {
10170888a09821a98ac0680fad765217302858e70fa4Paul Duffin      signalNextWaiter();
10180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
10190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    beginWaitingFor(guard);
10200888a09821a98ac0680fad765217302858e70fa4Paul Duffin    try {
10210888a09821a98ac0680fad765217302858e70fa4Paul Duffin      do {
10220888a09821a98ac0680fad765217302858e70fa4Paul Duffin        if (nanos < 0L) {
10230888a09821a98ac0680fad765217302858e70fa4Paul Duffin          return false;
10241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
10250888a09821a98ac0680fad765217302858e70fa4Paul Duffin        nanos = guard.condition.awaitNanos(nanos);
10260888a09821a98ac0680fad765217302858e70fa4Paul Duffin      } while (!guard.isSatisfied());
10270888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return true;
10280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    } finally {
10290888a09821a98ac0680fad765217302858e70fa4Paul Duffin      endWaitingFor(guard);
10301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
10311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
10321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
10331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
1034