> Hello!
>
> In the example below the main thread leaves Thread.wait() although nobody
> has called notify() or notifyAll(). Also no InterruptedException occurs.
>
> Has anybody an idea, why this "works" nevertheless?
"Spurious wakeups". It's in the Javadoc for the wait method.
Dan.

Signature
Daniel Dyer
http://www.uncommons.org
Andreas Heiduk - 01 Aug 2007 13:11 GMT
Hello!
>> Hello!
>>
[quoted text clipped - 4 lines]
>
> "Spurious wakeups". It's in the Javadoc for the wait method.
Well, this wakeup seems to be very reliable. With "spurious" I associated so
far "unreliable".
I think there is a "notify()" somewhere in the thread termination flow. But
where? And why? In platform specific code or on all platforms?
Has anybody hints in that direction?
Best regards
Andreas
> Hello!
>
> In the example below the main thread leaves Thread.wait() although nobody
> has called notify() or notifyAll(). Also no InterruptedException occurs.
>
> Has anybody an idea, why this "works" nevertheless?
It might be a spurious wakeup, as Daniel Dyer suggests.
It seems more likely, though, that notify() or notifyAll()
*is* being called. Not in your own code, clearly, but it
would not astonish me to learn that the JVM's own Thread
management called notify() on the Threads it manages. (I
don't *know* that it does, but it seems plausible.)
Whenever your code passes an object reference to some
other "agency" (the JVM itself, in this case) you no longer
have exclusive control of that object. The other agency can
call toString() on it, or equals() -- or notify().

Signature
Eric Sosman
esosman@ieee-dot-org.invalid
Tom Hawtin - 02 Aug 2007 14:56 GMT
>> In the example below the main thread leaves Thread.wait() although
>> nobody has called notify() or notifyAll(). Also no
>> InterruptedException occurs.
> It might be a spurious wakeup, as Daniel Dyer suggests.
> It seems more likely, though, that notify() or notifyAll()
> *is* being called. Not in your own code, clearly, but it
> would not astonish me to learn that the JVM's own Thread
> management called notify() on the Threads it manages. (I
> don't *know* that it does, but it seems plausible.)
It does. Actually this example is quite well known. It is in the bug
parade, and I think in Java Puzzlers.
> Whenever your code passes an object reference to some
> other "agency" (the JVM itself, in this case) you no longer
> have exclusive control of that object. The other agency can
> call toString() on it, or equals() -- or notify().
It's a case of threaded objects often using themselves as the lock
object. For instance, if you used a Hashtable as a lock, you wouldn't be
surprised that operations on the object interfered with your use of it
as a lock.
So my suggestions:
o Don't use random objects of complicated classes as locks.
o Don't use 'this' as a lock.
Instead create an object internal to your object for use as a lock:
public class MyClass {
private static class Lock { }
private static final Object lock = new Lock();
...
The reason for introducing an apparently useless Lock class is that the
class name appears in stack dumps. It's easier to see what is going on
than if the lock is reported as an instance of MyClass$Lock rather than
as a java.lang.Object.
Tom Hawtin