Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Java notify waiting threads implicitly?

I wrote a test app that should never stop. It issues t.wait() (t is a Thread object), but I never call notify. Why does this code end? Despite the main thread synchronizing on t, the spawned thread runs, so it doesn't lock this object.

public class ThreadWait {
    public static void main(String sArgs[]) throws InterruptedException {
        System.out.println("hello");
        Thread t = new MyThread();
        synchronized (t) {
            t.start();
            Thread.sleep(5000);
            t.wait();
            java.lang.System.out.println("main done");
        }
    }
}

class MyThread extends Thread {
    public void run() {
        for (int i = 1; i <= 5; i++) {
            java.lang.System.out.println("" + i);
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}

The result is that the main thread waits 5 seconds and during this time worker gives its output. Then after 5 seconds are finished, the program exits. t.wait() does not wait. If the main thread wouldn't sleep for 5 seconds (commenting this line), then t.wait() would actually wait until the worker finishes. Of course, join() is a method to use here, but, unexpectedly, wait() does the same thing as join(). Why?

Maybe the JVM sees that, since only one thread is running, there is no chance to notify the main thread and solves the deadlock. If this is true, is it a documented feature?

I'm testing on Windows XP, Java 6.

like image 704
Jarekczek Avatar asked Jan 27 '12 08:01

Jarekczek


People also ask

What happens when a thread executes wait ()?

So, when wait() method is called by a thread, then it gives up the lock on that resource and goes to sleep until some other thread enters the same monitor and invokes the notify() or notifyAll() method.

Can Java notify specific threads?

Java Thread notify() method This method gives the notification for only one thread which is waiting for a particular object. If we use notify() method and multiple threads are waiting for the notification then only one thread get the notification and the remaining thread have to wait for further notification.

Why wait () and notify () are in object class but not in thread class?

Hence, wait() and notify() methods are defined in Object class rather than Thread class. If wait() and notify() were on the Thread instead then each thread would have to know the status of every other thread and there is no way to know thread1 that thread2 was waiting for any resource to access.

What happens when the JVM encounters a wait () call?

wait() causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0). The current thread must own this object's monitor.


1 Answers

You're waiting on a Thread - and while most objects aren't implicitly notified, a Thread object is notified when the thread terminates. It's documented somewhere (I'm looking for it...) that you should not use wait/notify on Thread objects, as that's done internally.

This is a good example of why it's best practice to use a "private" object for synchronization (and wait/notify) - something which only your code knows about. I usually use something like:

private final Object lock = new Object();

(In general, however, it's cleaner to use some of the higher-level abstractions provided by java.util.concurrent if you can. As noted in comments, it's also a good idea to implement Runnable rather than extending Thread yourself.)

like image 55
Jon Skeet Avatar answered Oct 14 '22 05:10

Jon Skeet