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

David M. Lloyd david.lloyd at redhat.com
Fri Nov 11 14:21:10 EST 2011


I would personally never bother with propagation.  It is only a somewhat 
effective protection for poorly-written code.  Once you open the door of 
"well, I'll try to work around any poorly-written code which might or 
might not exist in the wild", it can be really hard to close again.  You 
might actually make real problems harder to find.

I find that the best policy engineering-wise is to always code to the 
contract and expect others to do as so as well (unless it's a case where 
a contract violation is detectable and handleable in a sensible way, 
e.g. an exception, which seems to come up most frequently in framework 
development as opposed to application development).

On 11/11/2011 12:05 PM, Dr Heinz M. Kabutz 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.
>
> I agree with David's assessment that it is much easier to convince
> people to use a while() loop to test their condition predicate if they
> know that "spurious wakeups" might occur. For many years I tried to
> explain during courses that this is wrong:
>
> public synchronized void put(Object o) {
> queue.add(o);
> notify();
> }
>
> public synchronized Object take() throws InterruptedException {
> if (queue.isEmpty()) {
> wait();
> }
> return queue.remove(0);
> }
>
> 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?"
>
> 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);
> }
>
>
> Regards
>
> Heinz


-- 
- DML


More information about the Concurrency-interest mailing list