com.google.common.util.concurrent

## Class Monitor

- java.lang.Object
- - com.google.common.util.concurrent.Monitor

-     @Beta
      public final class Monitor
      extends java.lang.Object

  A synchronization abstraction supporting waiting on arbitrary boolean conditions.

  This class is intended as a replacement for `ReentrantLock`. Code using `Monitor` is less error-prone and more readable than code using `ReentrantLock`, without significant performance loss. `Monitor` even has the potential for performance gain by optimizing the evaluation and signaling of conditions. Signaling is entirely implicit. By eliminating explicit signaling, this class can guarantee that only one thread is awakened when a condition becomes true (no "signaling storms" due to use of `Condition.signalAll`) and that no signals are lost (no "hangs" due to incorrect use of `Condition.signal`).

  A thread is said to occupy a monitor if it has entered the monitor but not yet left. Only one thread may occupy a given monitor at any moment. A monitor is also reentrant, so a thread may enter a monitor any number of times, and then must leave the same number of times. The enter and leave operations have the same synchronization semantics as the built-in Java language synchronization primitives.

  A call to any of the enter methods with void return type should always be followed immediately by a try/finally block to ensure that the current thread leaves the monitor cleanly:

         monitor.enter();
         try {
           // do things while occupying the monitor
         } finally {
           monitor.leave();
         }

  A call to any of the enter methods with boolean return type should always appear as the condition of an if statement containing a try/finally block to ensure that the current thread leaves the monitor cleanly:

         if (monitor.tryEnter()) {
           try {
             // do things while occupying the monitor
           } finally {
             monitor.leave();
           }
         } else {
           // do other things since the monitor was not available
         }

  ## Comparison with `synchronized` and `ReentrantLock`

  The following examples show a simple threadsafe holder expressed using `synchronized`, `ReentrantLock`, and `Monitor`.

  ### `synchronized`

  This version is the fewest lines of code, largely because the synchronization mechanism used is built into the language and runtime. But the programmer has to remember to avoid a couple of common bugs: The `wait()` must be inside a `while` instead of an `if`, and `notifyAll()` must be used instead of `notify()` because there are two different logical conditions being awaited.

         public class SafeBox<V> {
           private V value;

           public synchronized V get() throws InterruptedException {
             while (value == null) {
               wait();
             }
             V result = value;
             value = null;
             notifyAll();
             return result;
           }

           public synchronized void set(V newValue) throws InterruptedException {
             while (value != null) {
               wait();
             }
             value = newValue;
             notifyAll();
           }
         }

  ### `ReentrantLock`

  This version is much more verbose than the `synchronized` version, and still suffers from the need for the programmer to remember to use `while` instead of `if`. However, one advantage is that we can introduce two separate `Condition` objects, which allows us to use `signal()` instead of `signalAll()`, which may be a performance benefit.

         public class SafeBox<V> {
           private final ReentrantLock lock = new ReentrantLock();
           private final Condition valuePresent = lock.newCondition();
           private final Condition valueAbsent = lock.newCondition();
           private V value;

           public V get() throws InterruptedException {
             lock.lock();
             try {
               while (value == null) {
                 valuePresent.await();
               }
               V result = value;
               value = null;
               valueAbsent.signal();
               return result;
             } finally {
               lock.unlock();
             }
           }

           public void set(V newValue) throws InterruptedException {
             lock.lock();
             try {
               while (value != null) {
                 valueAbsent.await();
               }
               value = newValue;
               valuePresent.signal();
             } finally {
               lock.unlock();
             }
           }
         }

  ### `Monitor`

  This version adds some verbosity around the `Guard` objects, but removes that same verbosity, and more, from the `get` and `set` methods. `Monitor` implements the same efficient signaling as we had to hand-code in the `ReentrantLock` version above. Finally, the programmer no longer has to hand-code the wait loop, and therefore doesn't have to remember to use `while` instead of `if`.

         public class SafeBox<V> {
           private final Monitor monitor = new Monitor();
           private final Monitor.Guard valuePresent = new Monitor.Guard(monitor) {
             public boolean isSatisfied() {
               return value != null;
             }
           };
           private final Monitor.Guard valueAbsent = new Monitor.Guard(monitor) {
             public boolean isSatisfied() {
               return value == null;
             }
           };
           private V value;

           public V get() throws InterruptedException {
             monitor.enterWhen(valuePresent);
             try {
               V result = value;
               value = null;
               return result;
             } finally {
               monitor.leave();
             }
           }

           public void set(V newValue) throws InterruptedException {
             monitor.enterWhen(valueAbsent);
             try {
               value = newValue;
             } finally {
               monitor.leave();
             }
           }
         }

  Since:
    10.0

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static class` | `Monitor.Guard` A boolean condition for which a thread may wait.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `Monitor()` Creates a monitor with a non-fair (but fast) ordering policy.
    `Monitor(boolean fair)` Creates a monitor with the given ordering policy.

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `enter()` Enters this monitor.
    `boolean` | `enter(long time, java.util.concurrent.TimeUnit unit)` Enters this monitor.
    `boolean` | `enterIf(Monitor.Guard guard)` Enters this monitor if the guard is satisfied.
    `boolean` | `enterIf(Monitor.Guard guard, long time, java.util.concurrent.TimeUnit unit)` Enters this monitor if the guard is satisfied.
    `boolean` | `enterIfInterruptibly(Monitor.Guard guard)` Enters this monitor if the guard is satisfied.
    `boolean` | `enterIfInterruptibly(Monitor.Guard guard, long time, java.util.concurrent.TimeUnit unit)` Enters this monitor if the guard is satisfied.
    `void` | `enterInterruptibly()` Enters this monitor.
    `boolean` | `enterInterruptibly(long time, java.util.concurrent.TimeUnit unit)` Enters this monitor.
    `void` | `enterWhen(Monitor.Guard guard)` Enters this monitor when the guard is satisfied.
    `boolean` | `enterWhen(Monitor.Guard guard, long time, java.util.concurrent.TimeUnit unit)` Enters this monitor when the guard is satisfied.
    `void` | `enterWhenUninterruptibly(Monitor.Guard guard)` Enters this monitor when the guard is satisfied.
    `boolean` | `enterWhenUninterruptibly(Monitor.Guard guard, long time, java.util.concurrent.TimeUnit unit)` Enters this monitor when the guard is satisfied.
    `int` | `getOccupiedDepth()` Returns the number of times the current thread has entered this monitor in excess of the number of times it has left.
    `int` | `getQueueLength()` Returns an estimate of the number of threads waiting to enter this monitor.
    `int` | `getWaitQueueLength(Monitor.Guard guard)` Returns an estimate of the number of threads waiting for the given guard to become satisfied.
    `boolean` | `hasQueuedThread(java.lang.Thread thread)` Queries whether the given thread is waiting to enter this monitor.
    `boolean` | `hasQueuedThreads()` Returns whether any threads are waiting to enter this monitor.
    `boolean` | `hasWaiters(Monitor.Guard guard)` Queries whether any threads are waiting for the given guard to become satisfied.
    `boolean` | `isFair()` Returns whether this monitor is using a fair ordering policy.
    `boolean` | `isOccupied()` Returns whether this monitor is occupied by any thread.
    `boolean` | `isOccupiedByCurrentThread()` Returns whether the current thread is occupying this monitor (has entered more times than it has left).
    `void` | `leave()` Leaves this monitor.
    `boolean` | `tryEnter()` Enters this monitor if it is possible to do so immediately.
    `boolean` | `tryEnterIf(Monitor.Guard guard)` Enters this monitor if it is possible to do so immediately and the guard is satisfied.
    `void` | `waitFor(Monitor.Guard guard)` Waits for the guard to be satisfied.
    `boolean` | `waitFor(Monitor.Guard guard, long time, java.util.concurrent.TimeUnit unit)` Waits for the guard to be satisfied.
    `void` | `waitForUninterruptibly(Monitor.Guard guard)` Waits for the guard to be satisfied.
    `boolean` | `waitForUninterruptibly(Monitor.Guard guard, long time, java.util.concurrent.TimeUnit unit)` Waits for the guard to be satisfied.

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### Monitor

          public Monitor()

      Creates a monitor with a non-fair (but fast) ordering policy. Equivalent to `Monitor(false)`.

    - #### Monitor

          public Monitor(boolean fair)

      Creates a monitor with the given ordering policy.
      Parameters:
        `fair` - whether this monitor should use a fair ordering policy rather than a non-fair (but fast) one

  - ### Method Detail

    - #### enter

          public void enter()

      Enters this monitor. Blocks indefinitely.

    - #### enterInterruptibly

          public void enterInterruptibly()
                                  throws java.lang.InterruptedException

      Enters this monitor. Blocks indefinitely, but may be interrupted.
      Throws:
        `java.lang.InterruptedException` - if interrupted while waiting

    - #### enter

          public boolean enter(long time,
                      java.util.concurrent.TimeUnit unit)

      Enters this monitor. Blocks at most the given time.
      Returns:
        whether the monitor was entered

    - #### enterInterruptibly

          public boolean enterInterruptibly(long time,
                                   java.util.concurrent.TimeUnit unit)
                                     throws java.lang.InterruptedException

      Enters this monitor. Blocks at most the given time, and may be interrupted.
      Returns:
        whether the monitor was entered
      Throws:
        `java.lang.InterruptedException` - if interrupted while waiting

    - #### tryEnter

          public boolean tryEnter()

      Enters this monitor if it is possible to do so immediately. Does not block.

      Note: This method disregards the fairness setting of this monitor.

      Returns:
        whether the monitor was entered

    - #### enterWhen

          public void enterWhen(Monitor.Guard guard)
                         throws java.lang.InterruptedException

      Enters this monitor when the guard is satisfied. Blocks indefinitely, but may be interrupted.
      Throws:
        `java.lang.InterruptedException` - if interrupted while waiting

    - #### enterWhenUninterruptibly

          public void enterWhenUninterruptibly(Monitor.Guard guard)

      Enters this monitor when the guard is satisfied. Blocks indefinitely.

    - #### enterWhen

          public boolean enterWhen(Monitor.Guard guard,
                          long time,
                          java.util.concurrent.TimeUnit unit)
                            throws java.lang.InterruptedException

      Enters this monitor when the guard is satisfied. Blocks at most the given time, including both the time to acquire the lock and the time to wait for the guard to be satisfied, and may be interrupted.
      Returns:
        whether the monitor was entered, which guarantees that the guard is now satisfied
      Throws:
        `java.lang.InterruptedException` - if interrupted while waiting

    - #### enterWhenUninterruptibly

          public boolean enterWhenUninterruptibly(Monitor.Guard guard,
                                         long time,
                                         java.util.concurrent.TimeUnit unit)

      Enters this monitor when the guard is satisfied. Blocks at most the given time, including both the time to acquire the lock and the time to wait for the guard to be satisfied.
      Returns:
        whether the monitor was entered, which guarantees that the guard is now satisfied

    - #### enterIf

          public boolean enterIf(Monitor.Guard guard)

      Enters this monitor if the guard is satisfied. Blocks indefinitely acquiring the lock, but does not wait for the guard to be satisfied.
      Returns:
        whether the monitor was entered, which guarantees that the guard is now satisfied

    - #### enterIfInterruptibly

          public boolean enterIfInterruptibly(Monitor.Guard guard)
                                       throws java.lang.InterruptedException

      Enters this monitor if the guard is satisfied. Blocks indefinitely acquiring the lock, but does not wait for the guard to be satisfied, and may be interrupted.
      Returns:
        whether the monitor was entered, which guarantees that the guard is now satisfied
      Throws:
        `java.lang.InterruptedException` - if interrupted while waiting

    - #### enterIf

          public boolean enterIf(Monitor.Guard guard,
                        long time,
                        java.util.concurrent.TimeUnit unit)

      Enters this monitor if the guard is satisfied. Blocks at most the given time acquiring the lock, but does not wait for the guard to be satisfied.
      Returns:
        whether the monitor was entered, which guarantees that the guard is now satisfied

    - #### enterIfInterruptibly

          public boolean enterIfInterruptibly(Monitor.Guard guard,
                                     long time,
                                     java.util.concurrent.TimeUnit unit)
                                       throws java.lang.InterruptedException

      Enters this monitor if the guard is satisfied. Blocks at most the given time acquiring the lock, but does not wait for the guard to be satisfied, and may be interrupted.
      Returns:
        whether the monitor was entered, which guarantees that the guard is now satisfied
      Throws:
        `java.lang.InterruptedException`

    - #### tryEnterIf

          public boolean tryEnterIf(Monitor.Guard guard)

      Enters this monitor if it is possible to do so immediately and the guard is satisfied. Does not block acquiring the lock and does not wait for the guard to be satisfied.

      Note: This method disregards the fairness setting of this monitor.

      Returns:
        whether the monitor was entered, which guarantees that the guard is now satisfied

    - #### waitFor

          public void waitFor(Monitor.Guard guard)
                       throws java.lang.InterruptedException

      Waits for the guard to be satisfied. Waits indefinitely, but may be interrupted. May be called only by a thread currently occupying this monitor.
      Throws:
        `java.lang.InterruptedException` - if interrupted while waiting

    - #### waitForUninterruptibly

          public void waitForUninterruptibly(Monitor.Guard guard)

      Waits for the guard to be satisfied. Waits indefinitely. May be called only by a thread currently occupying this monitor.

    - #### waitFor

          public boolean waitFor(Monitor.Guard guard,
                        long time,
                        java.util.concurrent.TimeUnit unit)
                          throws java.lang.InterruptedException

      Waits for the guard to be satisfied. Waits at most the given time, and may be interrupted. May be called only by a thread currently occupying this monitor.
      Returns:
        whether the guard is now satisfied
      Throws:
        `java.lang.InterruptedException` - if interrupted while waiting

    - #### waitForUninterruptibly

          public boolean waitForUninterruptibly(Monitor.Guard guard,
                                       long time,
                                       java.util.concurrent.TimeUnit unit)

      Waits for the guard to be satisfied. Waits at most the given time. May be called only by a thread currently occupying this monitor.
      Returns:
        whether the guard is now satisfied

    - #### leave

          public void leave()

      Leaves this monitor. May be called only by a thread currently occupying this monitor.

    - #### isFair

          public boolean isFair()

      Returns whether this monitor is using a fair ordering policy.

    - #### isOccupied

          public boolean isOccupied()

      Returns whether this monitor is occupied by any thread. This method is designed for use in monitoring of the system state, not for synchronization control.

    - #### isOccupiedByCurrentThread

          public boolean isOccupiedByCurrentThread()

      Returns whether the current thread is occupying this monitor (has entered more times than it has left).

    - #### getOccupiedDepth

          public int getOccupiedDepth()

      Returns the number of times the current thread has entered this monitor in excess of the number of times it has left. Returns 0 if the current thread is not occupying this monitor.

    - #### getQueueLength

          public int getQueueLength()

      Returns an estimate of the number of threads waiting to enter this monitor. The value is only an estimate because the number of threads may change dynamically while this method traverses internal data structures. This method is designed for use in monitoring of the system state, not for synchronization control.

    - #### hasQueuedThreads

          public boolean hasQueuedThreads()

      Returns whether any threads are waiting to enter this monitor. Note that because cancellations may occur at any time, a `true` return does not guarantee that any other thread will ever enter this monitor. This method is designed primarily for use in monitoring of the system state.

    - #### hasQueuedThread

          public boolean hasQueuedThread(java.lang.Thread thread)

      Queries whether the given thread is waiting to enter this monitor. Note that because cancellations may occur at any time, a `true` return does not guarantee that this thread will ever enter this monitor. This method is designed primarily for use in monitoring of the system state.

    - #### hasWaiters

          public boolean hasWaiters(Monitor.Guard guard)

      Queries whether any threads are waiting for the given guard to become satisfied. Note that because timeouts and interrupts may occur at any time, a `true` return does not guarantee that the guard becoming satisfied in the future will awaken any threads. This method is designed primarily for use in monitoring of the system state.

    - #### getWaitQueueLength

          public int getWaitQueueLength(Monitor.Guard guard)

      Returns an estimate of the number of threads waiting for the given guard to become satisfied. Note that because timeouts and interrupts may occur at any time, the estimate serves only as an upper bound on the actual number of waiters. This method is designed for use in monitoring of the system state, not for synchronization control.