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