Java thread spontaneously waking up

java, multithreading, thread-safety

Solution

Yup, `Thread`s spontaneously wake up. The this is explicitly stated in the Javadoc:

"A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup."

You need to `wait` in a loop. This is also explicitly mentioned in the javadoc:

 synchronized (obj) {
     while (<condition does not hold>)
         obj.wait(timeout);
     ... // Perform action appropriate to condition
 }

In your case:

while (running) {
    synchronized (lock) {
        while (nextVal == null) {
            try {
                lock.wait();
            } catch (InterruptedException ie) {
                //oh well
            }
        }

        val = nextVal;
        nextVal = null;
    }
    ...do stuff with 'val'...
}

Problem

I've got a Java thread does something like this: ``` while (running) { synchronized (lock) { if (nextVal == null) { try { lock.wait(); } catch (InterruptedException ie) { continue; } } val = nextVal; nextVal = null; } ...do stuff with 'val'... } ``` Elsewhere I set the value like this: ``` if (val == null) { LOG.error("null value"); } else { synchronized (lock) { nextVal = newVal; lock.notify(); } } ``` Occasionally (literally once every couple of million times) nextVal will be set to null. I've tossed in logging messages and I can see that the order of execution looks like this: - thread1 sets nextVal to newVal - thread1 calls lock.notify() - thread2 wakes up from lock.wait() - thread2 sets val to nextVal - thread2 sets nextVal to null - thread2 does stuff with val - thread2 calls lock.wait() - thread2 wakes up from lock.wait() - no other thread has called lock.notify() and thread2 has not been interrupted - thread2 sets val to nextVal (which is null) - etc. I've explicitly checked and the lock is waking up a second time, it's not being interrupted. Am I doing something wrong here?

Original source