Threads can communicate with each other using wait(), notify() and notifyAll() methods. These methods are final methods of java.lang.Object class. That means every class in java will have these methods. Below are the method signatures of these methods.
1) public final void wait() throws InterruptedException
This method tells the currently executing thread to release the lock of this object and wait until some other thread acquires the same lock and notify it using either notify() or notifyAll() methods. This method throws InterruptedException if waiting thread is interrupted.
2)public final void notify()
This method wakes up one thread randomly that called wait() method on this object.
3) public final void notifyAll()
This method wakes up all the threads that called wait() method on this object. But, only one thread will acquire lock of this object depending upon the priority.
Important Note: These three methods must be called within synchronized method or block. Any thread which calls these methods must have lock of that object.
Below is an example for using wait() and notify() methods.
class Shared
{
synchronized void methodOne()
{
Thread t = Thread.currentThread();
System.out.println(t.getName()+" is releasing the lock and going to wait");
try
{
wait(); //releases the lock of this object and waits
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(t.getName()+" got the object lock back and can continue with its execution");
}
synchronized void methodTwo()
{
Thread t = Thread.currentThread();
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
notify(); //wakes up one thread randomly which is waiting for lock of this object
System.out.println("A thread which is waiting for lock of this object is notified by "+t.getName());
}
}
public class ThreadsInJava
{
public static void main(String[] args)
{
final Shared s = new Shared();
Thread t1 = new Thread()
{
public void run()
{
s.methodOne(); //t1 calling methodOne() of 's' object
}
};
Thread t2 = new Thread()
{
@Override
public void run()
{
s.methodTwo(); //t2 calling methodTwo() of 's' object
}
};
t1.start();
t2.start();
}
}
In this example, Thread t1 and t2 are sharing shared class object ‘s’. Thread t1 is calling methodOne() and thread t2 is calling methodTwo() of ‘s’ object. Both the methods are synchronized. That means, for any thread to enter these methods, they must acquire lock of ‘s’ object.
First, thread t1 acquires the object lock and enters methodOne(). Thread t2 waits for thread t1 to release the object lock. Thread t1 calls wait() method within methodOne(). As soon as, it calls wait() method, It releases the lock of ‘s’ object and goes for wait. Thread t2 acquires this lock and enters methodTwo(). After entering methodTwo(), thread t2 sleeps for 5 seconds and calls notify() method on this object. It wakes up thread t1 which is waiting for this object lock. As soon as, thread t2 releases the object lock after finishing it’s execution of methodTwo(), thread t1 acquires this lock and executes remaining statements of methodOne(). In this manner, both threads t1 and t2 communicate with each other and share the lock.
Some Things-To-Remember About wait(), notify() and notifyAll() :
- If a thread calls notify() method and more than one threads are waiting for the object lock, then only one thread will be notified randomly.
- When a thread calls notifyAll() method on an object, it notifies all the threads which are waiting for this object lock. But, only one thread will acquire this object lock depending upon priority.
- When you call sleep() method on a thread, thread goes to sleep with holding the object lock with it. But, if you call wait() method, thread releases the object lock and goes for sleep. This is the main difference between wait() and sleep() methods.
- wait(), notify() and notifyAll() are final methods of java.lang.Objectclass not java.lang.Thread class.
- wait(), notify() and notifyAll() – all these three methods throw IllegalMonitorStateException if the calling thread does not owns the object lock.
- wait() method is overloaded in Object class. There are two more wait() methods available in Object class. They are,
public final void wait(long timeOut) —> This makes current thread to wait until any other thread calls notify() or notifyAll() on this object or specified time(milli seconds) has elapsed.
public final void wait(long timeOut, int nanos) —> This makes current thread to wait until any other thread calls notify() or notifyAll() on this object or specified time(milli seconds + nano seconds) has elapsed
No comments:
Post a Comment