OK, to clarify the thoughts that have been floating around over the 
past dozen or so messages, I think there are two concrete proposals.
Proposal 1: a thread performing a wait should prefer throwing an IE 
over returning normally. In particular, if
* thread T1 calls m.wait()
* thread T2 calls T1.interrupt()
* thread T2 calls m.notify() or m.notifyAll()
Then T1 should exit the wait by throwing an IE.
Sun's current VM's fail this test (code attached at bottom).
Proposal 2: if a thread T1 performing a wait on object m is removed 
from the wait set via a call to m.notify(), and T1 exits the call to 
wait by throwing an IE, then the VM should ensure that another 
m.notify() is performed. Since spurious returns are allowed, one 
implementation of this would be to have any call to wait that throws 
an IE perform a re-notification.
-------
Commentary: the proposals are completely independent, we can adopt 
neither, one or the other, or both.
Sylvia didn't like the renotification rule, because it doesn't have 
the same semantics as non-deterministically making sure that notified 
threads and interrupted threads are disjoint. I don't think this is a 
realistic expectation, and in particular, I don't the example he gave 
is one that we should guarantee should work. The renotification rule 
isn't trivial, but it ensures that many design patterns for using 
notify() work, without requiring explicit calls by the programmer to 
notify in all of the catch blocks for IE.
        Bill
-----
class InterruptTest1 implements Runnable {
   int state = 0;
   public void run () {
        try {
        synchronized(this) {
                state = 1;
                notify();
                wait();
                if (state == 2)
                        System.out.println("wait returned normally");
                else
                        System.out.println("spurious return from wait");
                System.out.println("interrupted = " + Thread.interrupted());
                }
        } catch (InterruptedException e) {
                System.out.println("Got InterruptedException");
                }
        }
   public static void main(String args[]) throws Exception {
        InterruptTest1 it = new InterruptTest1();
        Thread t = new Thread(it);
        synchronized(it) {
                t.start();
                while (it.state == 0) it.wait();
                it.state = 2;
                // Interrupt before notify, so the call to wait
                // in the run method should throw an interrupted
                // exception rather than return in an interrupted state
                System.out.println("Interrupted, then notifying");
                t.interrupt();
                it.notify();
                }
        }
}
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:45 EDT