Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between wait/notify and wait/interrupt?

synchronized (Foo.class) {
    while (someCondition) {
        try {
            Foo.class.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();            
        }
    }
}

It seems that this thread both wakes when some other thread call interrupt() or notify() on this thread. Are there any differences between the two?

--EDIT--

I know one is for notifying an object, the other interrupts a thread. But both of these lead to the same consequence, that is, this thread is waken up, so what I want to ask is how these 2 situations' consequences are different from each other.

like image 984
Hải Phong Avatar asked May 27 '15 00:05

Hải Phong


People also ask

What's the difference between notify () and notifyAll ()?

In the case of the multiThreading, notify() method sends the notification to only one thread among the multiple waiting threads which are waiting for the send lock. While notifyAll() methods in the same context send notifications to all waiting threads instead of a single thread.

What is the difference between wait () and join ()?

The wait() is used for inter-thread communication while the join() is used for adding sequencing between multiple threads, one thread starts execution after first thread execution finished.

What is the difference between wait () and sleep () method?

Wait() method releases lock during Synchronization. Sleep() method does not release the lock on object during Synchronization. Wait() should be called only from Synchronized context. There is no need to call sleep() from Synchronized context.


2 Answers

When a thread calls notify on some monitor, it wakes up a single thread that's waiting on that monitor, but which thread gets woken is decided by the scheduler. (Alternatively a thread can call notifyAll, which wakes up all the threads waiting for that monitor, then they all contend for the monitor, then the losers go back to waiting.) That's why the target of the call is different, the notification is made to the monitor, which tells the scheduler to pick a thread to wake up.

Unlike notify, interruption targets a specific thread. And interruption does not require that the interrupted thread be waiting on a monitor. For a thread to call wait on a monitor it has to have acquired that monitor first, then wait releases that monitor until the thread is done waiting or is interrupted.

Oracle's recommendation is to use interruption only for cancellation. Also the classes in java.util.concurrent are designed to use interrupt for cancellation.

In your example interruption won't be very effective, because control doesn't leave the while loop, the thread still has to check the condition it's waiting on, and there's no check in the while loop condition for whether the interrupt flag is set. It's likely the thread that's interrupted will go right back to waiting.

In order to make this code quit once it's interrupted, rather then return to waiting, add a check for the interrupted flag status to the loop condition, and have the catch block set the interrupt flag (which gets reset when the exception is thrown):

synchronized (Foo.class) {
    while (someCondition && !Thread.currentThread().isInterrupted()) {
        try {
            Foo.class.wait();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();            
        }
    }
}
like image 161
Nathan Hughes Avatar answered Sep 19 '22 13:09

Nathan Hughes


Basically, you are not looking for a text book difference but difference in their uses cases.

As folks have already pointed out, waking up the thread is not the only consequence but calling t1.interrupt() from Thread t2 for t1 will cause an InterruptedException in thread t1 and that is a big difference between Object.notify() and Thread.interrupt().

You should understand that its method Object.wait() which throws checked InterruptedException and forces you to handle it. Object.wait.

InterruptedException - if any thread interrupted the current thread before or while the current thread was waiting for a notification. The interrupted status of the current thread is cleared when this exception is thrown.

Then you should consult this question to get an idea about handling this exception.

Difference between the two lies in the fact that one is for inter thread communication for usual logical programing stuff ( wait & notify ) and other one ( interrupt) is for preemptive thread cancellation / termination even in cases of blocking operations. You have to note that Java doesn't provide any mechanism to preemptively cancel a thread so you have to use interrupt mechanism for that purpose ( Obviously, if that is needed in your case. You might very well ignore this Exception if not applicable in your case).

Java doesn't restrict your actions after InterruptedException and you can do anything you want but using it for things other than implementing Thread Cancellation Policy is not advised. Thread Cancellation Policy is often ignored and less discussed area when programmers write multi threaded programs and that is why you might be finding it difficult to understand the use case.

What does an API method like BlockingQueue.put(..) is trying to tell you by throwing InterruptedException is that even its blocking operation can be preemptively terminated. Its not necessary that all blocking API methods will provide you that facility.

Cancellation/Termination of a thread using Thread.interrupt() is not a forceful but cooperative mechanism and is just a request not an order.

Your use of e.printStackTrace(); is strongly discouraged since this is usually not an error, if intention is to log it as an error.

Hope it helps !!

like image 25
Sabir Khan Avatar answered Sep 18 '22 13:09

Sabir Khan