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?