Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2007

Tip: Looking for answers? Try searching our database.

Why does Thread.wait() return here?

Thread view: 
Andreas Heiduk - 01 Aug 2007 12:34 GMT
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?

JVM: Java Sun JRE 1.5.0.10

Best regards
Andreas

public class ThreadWait implements Runnable {
   public static void main(String[] args) {
       try {
           Thread child = new Thread(new ThreadWait(), "Child-Thread");
           child.start();
           synchronized (child) {
               System.err.println("entering wait");
               child.wait();
               System.err.println("left wait");
           }
       }catch(Throwable t){
           t.printStackTrace();
       }
   }

   public void run(){
       try {
           System.err.println("entering sleep");
           Thread.sleep(2*1000);
           System.err.println("left sleep");
       }catch(Throwable t){
           t.printStackTrace();
       }
   }
}
Daniel Dyer - 01 Aug 2007 12:55 GMT
> 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
Eric Sosman - 01 Aug 2007 13:16 GMT
> 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


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.