2

I get a strange thing when I learn how to using wait and notify, the below two parts code are similar, but their result are so different, why?

class ThreadT implements Runnable{



public void run()
  {
    synchronized (this) {

        System.out.println("thead:"+Thread.currentThread().getName()+" is over!");

    }

   }
}

public class TestWait1 {


public static void main(String[] args) {

    Thread A = new Thread(new ThreadT(),"A");
     A.start();
    synchronized (A) {

        try {
            A.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    System.out.println(Thread.currentThread().getName()+" is over");

}

}

Result:
thead:A is over!
main is over

class ThreadD implements Runnable{

Object o  ;

public ThreadD(Object o)
{
    this.o = o;
}

public void run()
{
    synchronized (o) {

        System.out.println("thead:"+Thread.currentThread().getName()+" is over!");

    }


}
}

public class TestWait2 {


public static void main(String[] args) {

        Object o = new Object();

    Thread A = new Thread(new ThreadD(o),"A");

     A.start();

    synchronized (o) {

        try {
            o.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    System.out.println(Thread.currentThread().getName()+" is over");

}

}

Result:
thead:A is over!

why the main function can finish in the first sample, but the second sample main function can't. what are they different?

Peter Xu
  • 21
  • 2

2 Answers2

7

If you're calling wait() on an Object, this waits until something calls notify() on it. In your second example, there is no one calling notify(), so the wait goes on forever. In the first example, the termination of the thread calls notifyAll() on it, which causes the wait() to complete.

yole
  • 92,896
  • 20
  • 260
  • 197
  • 1
    Important note to OP: *never call wait/notify on an instance of `Thread`*. – Marko Topolnik Feb 28 '15 at 18:05
  • @MarkoTopolnik, please advise why never call wait/notify on an instant of Thread? thanks. – Peter Xu Mar 02 '15 at 13:07
  • @PeterXu Calling `notify()` on a Thread is a very bad idea because `notify()` will wake at most one `wait()`er. If it's not a thread that you intended to wake, then your notification will be _lost_ and you program is likely to hang. Calling `wait()` on a Thread object, _if you do it right_, is harmless except that your `wait()`er may be woken up at times when there was no work for it to do (a.k.a., "spurious wakeup"), and calling `notifyAll()` is equally harmless except that you may spuriously wake up threads that you did not mean to wake. – Solomon Slow Mar 02 '15 at 14:00
  • @PeterXu did you read the Javadoc on `Thread#join`, which yole linked to? It's explained there. I just added that as an explicit comment so it doesn't get lost behind the link. Basically, the thread uses the `Thread`'s monitor for its own internal coordination. It's notoriously bad design, but we're stuck with it. – Marko Topolnik Mar 02 '15 at 14:36
0

@yole is right. On "Object o" no body calls notify but in first case in which you are waiting on Thread instance notifyall is called by Thread instance when it exits.

Here is another web link which refers to same question you have asked.

Community
  • 1
  • 1
Tarun Chawla
  • 508
  • 4
  • 17