AgostinoX
AgostinoX

Reputation: 7683

if java wait() is called on a Thread, the method exits also on run() method termination

I'm puzzled with a particular use case of the wait() method.
According with javadoc, wait should end when one of the following condition happens:

In the case in which the object i'm waiting on is itself a Thread, it happens that the wait() exits even if no notify() has been called, and no one of the above conditions holds. But it happens when the Thread.run() method ends. While this behavior may make sense, shouldn't it be documented inside of Thread javadoc? I find it very confusing also because it overlaps with join() behavior.

This is my test code:

public static class WorkerThread extends Thread {

    @Override public void run() {

        try{
           System.out.println("WT: waiting 4 seconds");
           Thread.sleep(4000);

           synchronized (this) {
            notify();
           }

           System.out.println("WT: waiting for 4 seconds again");
           Thread.sleep(4000);
           System.out.println("WT: exiting");

        } catch (InterruptedException ignore) {
            ignore.printStackTrace();
        }

    }

}

public static void main (String [] args) throws InterruptedException {

    WorkerThread w = new WorkerThread();

    w.start();

    synchronized(w) {
        w.wait();
        System.out.println("MT: The object has been notified by the thread!");
    }

    synchronized(w) {

        w.wait(); //THIS FINISHES WITHOUT notify(), interrupt() OR TIMEOUT!

        System.out.println("MT: The thread has been notified again!");
    }

}

Upvotes: 2

Views: 1695

Answers (3)

Score_Under
Score_Under

Reputation: 1216

If you want predictable and controllable wait/notify behaviour, share an Object between the thread and the method waiting on it.

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533530

It is a common anti-pattern to extend Thread directly. The problem is you can have all sorts of unintended consequences as Thread is a complex class. One thing it does is notify threads trying to join() the thread when it stops. This has the effect of notifying any thread waiting on that thread object.

A common Java puzzler is to miss use a class which extends Thread.

BTW While using wait()/notify() has been old school for more than 9 years now, you can still use them in rare situations. If you do you should change the state of something in the notify() block and wait for that state change when you wait(). This is because if you call notify before wait, it is lost and wait() can exist spuriously, even if you don't extend thread.

Upvotes: 5

JB Nizet
JB Nizet

Reputation: 691765

It is documented since Java 7, in the documentation of the join() method:

As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

Upvotes: 7

Related Questions