JavaMemoryModel: Reconsidering prioritized InterruptedExceptions

From: Doug Lea (dl@cs.oswego.edu)
Date: Wed Nov 26 2003 - 08:56:23 EST


First, recapping background. The existing Object.wait spec says:

   If the current thread is interrupted by another thread while it is
   waiting, then an InterruptedException is thrown.

Some people have interpreted "waiting" to mean blocked waiting for a
notification, while others think it encompasses both waiting for
notification and waiting to re-acquire lock. This has led to all sorts
of disagreements over the years about what does happen and what should
happen. While you might think of this as an angels-on-pinheads
debate, it also shows in Java code that is implicitly dependent on one
or the other interpretation, so is at best non-portable. This can
arise only in a few designs using notify() as opposed to notifyAll(),
so doesn't have widespread impact. Further, it is pretty easy to write
such code in a way that is not dependent on which way JVMs implement
this. But the issue still needs to be addressed by JSR133 in order to
clarify requirements.

In the draft JSR133 spec we "resolve" this by legitimizing either of
these interpretations. This is phrased in terms of behavior when a
thread is notified and then interrupted, which is the case in which
different implementations may differ. The prefer-notify policy returns
normally if the thread was notified before it was interrupted; the
prefer-IE policy throws InterruptedException in this case. These
policies can be made otherwise equivalent with respect to issues like
avoiding spurious notifications without much of an implementation
burden on JVMs,.

But as Sylvia has noticed, it is tricky to specify this in a way that
avoids unintended implications about sequences of interrupts and
notifies -- the current draft needs some rewording if we continue to
take this approach. Also, allowing both policies makes it harder to
model behavior. Neither of these especially bother me -- people doing
modeling and specification can somehow cope. But it does bother me
that if the spec is too subtle and complicated, programmers will
ignore it and instead rely on the particular behavior of the JVM they
happen to be using during development, in which case we are no better
off than now.

The only plausible path for making the spec simpler and more
deterministic is to require the prefer-notify policy.
The Object.wait spec can just add three words:
   If the current thread is interrupted by another thread while it is
   waiting FOR A NOTIFICATION...
and omit all other discussion of interrput/notify interactions.
Similar simplifications apply to the "full" version in JSR133 draft.
All ways of doing this for prefer-IE policy are less simple because
they must further describe notify-then-interrupt interactions.

There aren't any known challenging JVM implementation consequences of
this decision; it is a matter of restricting freedom. (In fact, the
prefer-IE policy is harder to implement on most systems.)

This choice is unfortunate in that the prefer-IE policy is always
better in systems that must deal with timely thread cancellation. If
it is not allowed, JVMs won't be able to help make systems more
responsive to interruptions as a quality-of-implementation feature.

But, as the main advocate of prefer-IE policy, I'm getting to think it
is worth giving this up for the sake of avoiding yet more years of
confusion and unintended non-portability.

-Doug
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:54 EDT