[concurrency-interest] Propagation of signals to non-interrupted thread

Martin Buchholz martinrb at google.com
Fri Nov 11 13:48:37 EST 2011

On Fri, Nov 11, 2011 at 10:05, Dr Heinz M. Kabutz
<heinz at javaspecialists.eu>wrote:

> Yes, the spurious wakeup is definitely part of the game.  One of my
> customers had a system that basically imploded in Java 6 because they
> happened frequently under heavy load.
> Interesting.

> My argument was:  Thread 1 calls take, queue is empty and is parked with
> wait() and thus lets go of the lock.  Thread 2 comes along, gets the lock,
> adds an element and calls notify(), which thus wakes up thread 1.  However,
> thread 1 cannot proceed until he has the lock again.  Thread 2 now returns
> the lock, but at that instant, Thread 3 comes along and calls take().
>  Finding the queue non-empty, it removes the first element and returns.
>  Thread 1 now finally gets the lock and calls queue.remove(0), which
> results in a NoSuchElementException.
> A long argument, which is much easier to argue with spurious wakeups :-)
>  "Thread 1 is waiting, but can wake up due to a spurious signal.  These
> things really do happen in production.  Any questions?"

For Object.wait, spurious wakeups are still possible.

The "long argument" is hard for humans to understand, but is what I
consider the "real" reason to call Condition.await in a loop.  When
teaching this material, it might be easier to say,

"Always call wait/await in a loop. If you don't, you will have mysterious
failures in production.  If you care about the long story, or want to
understand how java monitors *really* work, we can discuss in depth later."

> Some of my customers are still using Java 1.4.2.  Do we need to propagate
> the signal if we use low-level synchronized?  I would feel most comfortable
> even doing this in Java 5+, even if it is not necessary, since the take()
> method needs to cope with spurious signals anyway.
> public synchronized Object take() throws InterruptedException {
>  while (queue.isEmpty()) {
>   try {
>     wait();
>   } catch(InterruptedException ex) {
>     notify();
>     throw ex;
>   }
>  }
>  return queue.remove(0);
> }

My condolences for all of you out there who are trying to write concurrent
code for Java 1.4.2.  If I were doing that, I would also be paranoid and
notify() on catching InterruptedException.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20111111/23cb0dbb/attachment.html>

More information about the Concurrency-interest mailing list