`Object.wait()` is supposed to block until either another thread invokes the
`Object.notify()` or `Object.notifyAll()` method, or a specified amount of time
has elapsed. The various `Condition.await()` methods have similar behavior.
However, it is possible for a thread to wake up without either of those
occurring; these are called *spurious wakeups*.

Because of spurious wakeups, `Object.wait()` and `Condition.await()` must always
be called in a loop. The correct fix for this varies depending on what you are
trying to do.

## Wait until a condition becomes true

The incorrect code for this typically looks like:

Thread 1:

```java
synchronized (this) {
  if (!condition) {
    wait();
  }
  doStuffAssumingConditionIsTrue();
}
```

Thread 2:

```java
synchronized (this) {
  condition = true;
  notify();
}
```

If the call to `wait()` unblocks because of a spurious wakeup, then
`doStuffAssumingConditionIsTrue()` will be called even though `condition` is
still false. Instead of the `if`, you should use a `while`:

Thread 1:

```java
synchronized (this) {
  while (!condition) {
    wait();
  }
  doStuffAssumingConditionIsTrue();
}
```

This ensures that you only proceed to `doStuffAssumingConditionIsTrue()` if
`condition` is true. Note that the check of the condition variable must be
inside the synchronized block; otherwise you will have a race condition between
checking and setting the condition variable.

## Wait until an event occurs

The incorrect code for this typically looks like:

Thread 1:

```java
synchronized (this) {
  wait();
  doStuffAfterEvent();
}
```

Thread 2:

```java
// when event occurs
synchronized (this) {
  notify();
}
```

If the call to `wait()` unblocks because of a spurious wakeup, then
`doStuffAfterEvent()` will be called even though the event has not yet occurred.
You should rewrite this code so that the occurrence of the event sets a
condition variable as well as calls `notify()`, and the `wait()` is wrapped in a
while loop checking the condition variable. That is, it should look just like
[the previous example](#wait_until_a_condition_becomes_true).

## Wait until either a condition becomes true or a timeout occurs

The incorrect code for this typically looks like:

```java
synchronized (this) {
  if (!condition) {
    wait(timeout);
  }
  doStuffAssumingConditionIsTrueOrTimeoutHasOccurred();
}
```

A spurious wakeup could cause this to proceed to
`doStuffAssumingConditionIsTrueOrTimeoutHasOccurred()` even if the condition is
still false and time less than the timeout has elapsed. Instead, you should
write:

```java
synchronized (this) {
  long now = System.currentTimeMillis();
  long deadline = now + timeout;
  while (!condition && now < deadline) {
    wait(deadline - now);
    now = System.currentTimeMillis();
  }
  doStuffAssumingConditionIsTrueOrTimeoutHasOccurred();
}
```

## Wait for a fixed amount of time

First, a warning: This type of waiting/sleeping is often done when the real
intent is to wait until some operation completes, and then proceed. If that's
what you're trying to do, please consider rewriting your code to use one of the
patterns above. Otherwise you are depending on system-specific timing that
*will* change when you run on different machines.

The incorrect code for this typically looks like:

```java
synchronized (this) {
  // Give some time for the foos to bar
  wait(1000);
}
```

A spurious wakeup could cause this not to wait for a full 1000 ms. Instead, you
should use `Thread.sleep()`, which is not subject to spurious wakeups:

```java
Thread.sleep(1000);
```

## Wait forever

The incorrect code for this typically looks like:

```java
synchronized (this) {
  // wait forever
  wait();
}
```

A spurious wakeup could cause this not to wait forever. You should wrap the call
to `wait()` in a `while (true)` loop:

```java
synchronized (this) {
  // wait forever
  while (true) {
    wait();
  }
}
```

## More information

See Java Concurrency in Practice section 14.2.2, "Waking up too soon,"
[the Javadoc for `Object.wait()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#wait-long-),
and the "Implementation Considerations" section in
[the Javadoc for `Condition`](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html).
