Java — Inter Thread Communication : wait(), notify() and notifyAll() | Code Factory
Index Page : Link
Donate : Link
WordPress Blog : Link
- 2 Threads can communicate with each other by wait(), notify() and notifyAll() methods.
- The Thread which is expecting updation is responsible to call wait() method then immediately the Thread will entered into waiting state.
- The Thread which is responsible to perform updation after performing updation it is responsible to call notify() method then waiting Thread will get that notification and continue with those updation items.
- wait(), notify() and notifyAll() methods present in Object class but not in Thread class because Thread can call this methods on any Java objects.
- To call wait(), notify() or notifyAll() methods on any object, thread should be owner of that object that is the thread has lock of that object that is the thread should be inside Synchronized area. Hence we can wait(), notify() and notifyAll() methods only from Synchronized area otherwise we will get runtime exception (RE) saying
IllegalMonitorStateException
. - If a thread calls wait() method on any object it immediately release the lock of that particular object and entered into waiting state.
- If a thread calls notify() method on any object it release the object of that object but may not immediately, exapt wait(), notify() and notifyAll(). There is no any other method where thread release the lock.
Method Is thread release lock?
yield() -> No
join() -> No
sleep() -> No
wait() -> Yes
notify() -> Yes
notifyAll() -> Yes
Which of the following is valid :
1. If a thread calls wait() method immediately it will entered into waiting state without releasing any lock?
- Invalid
2. If a thread calls wait() method it release the lock of that object but may not immediately.
- Invalid
3. If a thread calls wait() method on any object it release all locks acquired by that thread and immediately entered into waiting state.
- Invalid
4. If a thread calls wait() method on any object ot immediately release lock of that particular object and entered into waiting state.
- Valid
5. If a thread calls notify() method on any object it immediately release lock of that particular object.
- Invalid
6. If a thread calls notify() method on any object it release the lock of that object but may not immediately.
- Valid
/*
Reference : https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html
*//* Causes the cur+rent 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). */
public final void wait() throws InterruptedException/* Causes the current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed. */
public final void wait(long timeout) throws InterruptedException/* Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed. */
public final void wait(long timeout, int nanos) throws InterruptedException/* Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods. */
public final void notify()/* Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods. */
public final void notifyAll()
- Every wait() method throws
InterruptedException
which is checked exception. Hence whenever we are using wait() method compulsary we should handle this IE either by try catch or throws keyword otherwise we will get compile time error.
package com.example.thread;/**
* @author code.factory
*
*/
public class ThreadTest {
public static void main(String... args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
synchronized (t) {
System.out.println("main thread calling wait() method");
t.wait();
System.out.println("main thread got notification");
System.out.println(t.total);
}
}
}class MyThread extends Thread {
int total = 0;
public void run() {
synchronized (this) {
System.out.println("child thread start calculation");
for(int i=0; i<5; i++) {
total = total + i;
}
System.out.println("child thread giving notification");
this.notify();
}
}
}
Output :
main thread calling wait() method
child thread start calculation
child thread giving notification
main thread got notification
10
Producer Consumer Problem :
- Producer thread is responsible to produce items to the queue and consumer thread is responsible to consume items from the queue.
- If queue is empty then consumer thread will call wait() method and entered into waiting state.
- After producing items to the queue, producer thread is responsible to call notify() method then waiting consumer will get that notification and continue it’s execution with the updated items.
Difference Between notidy() and notifyAll() :
- We can use notify() method to give the notification for only one waiting thread, If multiple threads are waiting then only one thread will be notify and the remaining threads have to wait for further notifications.
- Which thhread will be notify we can’t expect. It’s depend on JVM.
- We can use notifyAll() to give the notification for all waiting threads of a particular object, even though multiple threads notified but execution will be performed one by one because threads require locks but only one lock is available.
- On which object we are calling wait object thread require lock of that particular object. For example if we are calling wait() method on s1 then we have to get lock of s1 object not on s2.