jsr107 / jsr107spec

JSR107 Cache Specification
Apache License 2.0
413 stars 164 forks source link

Spurious wakeup bug CompletionListenerFuture #348

Closed pveentjer closed 8 years ago

pveentjer commented 8 years ago

The following code fails to deal with spurious wakeup. It is allowed that the thread is notified without a reason. To deal with this situation, the if(!completed) should be while(!completed). Of course the remaining timeout needs to be corrected.

 @Override
  public Void get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
    synchronized (this) {
      if (!isCompleted) {
        unit.timedWait(this, timeout);
      }

      if (isCompleted) {
        if (exception == null) {
          return null;
        } else {
          throw new ExecutionException(exception);
        }
      } else {
        throw new TimeoutException();
      }
    }
  }
cruftex commented 8 years ago

Good finding. Just learned something.

Its described at Object.wait():

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied.

cruftex commented 8 years ago

Further tracked by #320