The Object class has three methods, wait(), notify(), and notifyAll() that help threads
Communicate.
Suppose a mail processor thread has to keep checking if there is any mail to process.
For example,
if one thread is a mail-delivery thread and one thread is a mail-processor thread,
the mail-processor thread has to keep checking to see if there's any mail to process.
Using the wait and notify mechanism, the mail-processor thread could check for
mail, and if it doesn't find any it can say, "Hey, I'm not going to waste my time
checking for mail every two seconds. I'm going to go hang out, and when the mail
deliverer puts something in the mailbox, have him notify me so I can go back to
runnable and do some work."
In other words, using wait() and notify() lets one thread put itself into a "waiting room" until some other thread notifies it that there's a reason to come back out.
wait(), notify(), and notifyAll() must be called from within a synchronized
context! A thread can't invoke a wait or notify method on an object unless it owns
that object's lock.
Example:
1. class ThreadA {
2. public static void main(String [] args) {
3. ThreadB b = new ThreadB();
4. b.start();
5.
6. synchronized(b) {
7. try {
8. System.out.println("Waiting for b to complete...");
9. b.wait();
10. } catch (InterruptedException e) {}
11. System.out.println("Total is: " + b.total);
12. }
13. }
14. }
15.
16. class ThreadB extends Thread {
17. int total;
18.
19. public void run() {
20. synchronized(this) {
21. for(int i=0;i<100;i++) {
22. total += i;
23. }
24. notify();
25. }
26. }
27. }
Explanation:
This program contains two objects with threads: ThreadA contains the main
thread and ThreadB has a thread that calculates the sum of all numbers from 0
through 99.
As soon as line 4 calls the start() method, ThreadA will continue
with the next line of code in its own class, which means it could get to line 11
before ThreadB has finished the calculation. To prevent this, we use the wait()
method in line 9.
in line 6 the code synchronizes itself with the object b—this is because in
order to call wait() on the object, ThreadA must own a lock on b. For a thread to
call wait() or notify(), the thread has to be the owner of the lock for that object.
When the thread waits, it temporarily releases the lock for other threads to use, but
it will need it again to continue execution.
The flow is like this
synchronized(anotherObject) { // this has the lock on anotherObject
try {
anotherObject.wait();
// the thread releases the lock and waits
// To continue, the thread needs the lock,
// so it may be blocked until it gets it.
} catch(InterruptedException e){}
}
The preceding code waits until notify() is called on anotherObject.
synchronized(this) { notify(); }
First when we call the wait() the object releases the lock to another object. Then another object does its job again releases the lock to the original object.
When the wait() method is invoked on an object, the thread executing
that code gives up its lock on the object immediately. However, when notify() is called,
that doesn’t mean the thread gives up its lock at that moment. If the thread is still
completing synchronized code, the lock is not released until the thread moves out of
synchronized code. So just because notify() is called doesn’t mean the lock becomes
available at that moment.
Using notifyAll( ) When Many Threads May Be Waiting
it's preferable to notify all of the threads that are waiting on a
particular object. If so, you can use notifyAll() on the object to let all the threads
rush out of the waiting area and back to runnable.
notifyAll(); // Will notify all waiting threads
All of the threads will be notified and start competing to get the lock. As the lock
is used and released by each thread, all of them will get into action without a need
for further notification.
Example:
class Reader extends Thread {
Calculator c;
public Reader(Calculator calc) {
c = calc;
}
public void run() {
synchronized(c) {
try {
System.out.println("Waiting for calculation...");
c.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + c.total);
}}
public static void main(String [] args) {
Calculator calculator = new Calculator();
new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
calculator.start();
}}
class Calculator extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i=0;i<100;i++) {
total += i;
}
notifyAll();
}}}
Key points:
❑ The wait() method lets a thread say, "there's nothing for me to do now, so
put me in your waiting pool and notify me when something happens that I
care about." Basically, a wait() call means "wait me in your pool," or "add
me to your waiting list."
❑ The notify() method is used to send a signal to one and only one of the
threads that are waiting in that same object's waiting pool.
❑ The notify() method can NOT specify which waiting thread to notify.
❑ The method notifyAll() works in the same way as notify(), only it sends
the signal to all of the threads waiting on the object.
❑ All three methods—wait(), notify(), and notifyAll()—must be
called from within a synchronized context! A thread invokes wait() or
notify() on a particular object, and the thread must currently hold the lock
on that object.
Our Training Institute 7eleven Arthashatra provides real-time and placement focused Java trainingcourses in Chennai . Our Java training course includes basic to advanced levels.Our Java training centers are equipped with lab facilities and excellent infrastructure.We Provide regular training classes(day time classes), weekend training classes for Java training course in our centres located across Chennai. Our Java course and syllabus is designed to get the placement in major MNC companies in Chennai as soon as you complete the Java training course. We have designed our Java course content and syllabus based on students requirement to achieve everyone's career goal.
ReplyDelete