wait(), notify() and notifyAll() in Java - A tutorial

By: Jagan Emailed: 1768 times Printed: 2515 times    

Latest comments
By: rohit kumar - how this program is work
By: Kirti - Hi..thx for the hadoop in
By: Spijker - I have altered the code a
By: ali mohammed - why we use the java in ne
By: ali mohammed - why we use the java in ne
By: mizhelle - when I exported the data
By: raul - no output as well, i'm ge
By: Rajesh - thanx very much...
By: Suindu De - Suppose we are executing

The use of the implicit monitors in Java objects is powerful, but you can achieve a more subtle level of control through inter-process communication. As you will see, this is especially easy in Java.

Multithreading replaces event loop programming by dividing your tasks into discrete and logical units. Threads also provide a secondary benefit: they do away with polling. Polling is usually implemented by a loop that is used to check some condition repeatedly. Once the condition is true, appropriate action is taken. This wastes CPU time. For example, consider the classic queuing problem, where one thread is producing some data and another is consuming it. To make the problem more interesting, suppose that the producer has to wait until the consumer is finished before it generates more data. In a polling system, the consumer would waste many CPU cycles while it
waited for the producer to produce. Once the producer was finished, it would start polling, wasting more CPU cycles waiting for the consumer to finish, and so on. Clearly, this situation is undesirable.

To avoid polling, Java includes an elegant interrocess communication mechanism via the wait( ), notify( ), and notifyAll( ) methods. These methods are implemented as final methods in Object, so all classes have them. All three methods can be called only from within a synchronized method. Although conceptually advanced from a computer science perspective, the rules for using these methods are actually quite simple:

  • wait( ) tells the calling thread to give up the monitor and go to sleep until some other
    thread enters the same monitor and calls notify( ).
  • notify( ) wakes up the first thread that called wait( ) on the same object.
  • notifyAll( ) wakes up all the threads that called wait( ) on the same object. The
    highest priority thread will run first.

These methods are declared within Object, as shown here:

final void wait( ) throws InterruptedException
final void notify( )
final void notifyAll( )

Additional forms of wait( ) exist that allow you to specify a period of time to wait. The following sample program incorrectly implements a simple form of the producer/consumer problem. It consists of four classes: Q, the queue that you're trying to synchronize; Producer, the threaded object that is producing queue entries; Consumer, the threaded object that is consuming queue entries; and PC, the tiny class that creates the single Q, Producer, and Consumer.

// An incorrect implementation of a producer and consumer.
class Q {
int n;
synchronized int get() {
System.out.println("Got: " + n);
return n;
}
synchronized void put(int n) {
this.n = n;
System.out.println("Put: " + n);
}
}

class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}

class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
}

class PC {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}

Although the put( ) and get( ) methods on Q are synchronized, nothing stops the producer from overrunning the consumer, nor will anything stop the consumer from consuming the same queue value twice. Thus, you get the erroneous output shown here (the exact output will vary with processor speed and task load):

Put: 1
Got: 1
Got: 1
Got: 1
Got: 1
Got: 1
Put: 2
Put: 3
Put: 4
Put: 5
Put: 6
Put: 7
Got: 7

As you can see, after the producer put 1, the consumer started and got the same 1 five times in a row. Then, the producer resumed and produced 2 through 7 without letting the consumer have a chance to consume them.

The proper way to write this program in Java is to use wait( ) and notify( ) to signal in both directions, as shown here:

// A correct implementation of a producer and consumer.
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
if(!valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
if(valueSet)
try {
wait();
} catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}

class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}
}
}

class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
}

class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}

Inside get( ), wait( ) is called. This causes its execution to suspend until the Producer notifies you that some data is ready. When this happens, execution inside get( ) resumes. After the data has been obtained, get( ) calls notify( ). This tells Producer that it is okay to put more data in the queue. Inside put( ), wait( ) suspends execution until the Consumer has removed the item from the queue. When execution resumes, the next item of data is put in the queue, and notify( ) is called. This tells the Consumer that it should now remove it.

Here is some output from this program, which shows the clean synchronous behavior:

Put: 1
Got: 1
Put: 2
Got: 2
Put: 3
Got: 3
Put: 4
Got: 4
Put: 5
Got: 5

This tutorial is an extract from the book "The complete Reference Java 2" by Herbert Schildt


Java Home | All Java Tutorials | Latest Java Tutorials

Sponsored Links

If this tutorial doesn't answer your question, or you have a specific question, just ask an expert here. Post your question to get a direct answer.



Bookmark and Share

Comments(59)


1. View Comment

Thanks for the article. I got some clearance now. Thank you again.

View Tutorial          By: Reddy at 2008-03-15 00:02:17
2. View Comment

nice article, many thanx :)

View Tutorial          By: Unknown at 2008-10-16 21:09:02
3. View Comment

very cool you said it! many thanks it's really cool 'n' clear

View Tutorial          By: ArAsh at 2008-12-11 06:41:13
4. View Comment

thank you. it was very useful.

View Tutorial          By: ravindar at 2009-01-09 01:04:15
5. View Comment

Great job!
Lot of things cleared...


View Tutorial          By: alok at 2009-03-18 10:45:25
6. View Comment

i have clear that notify and wait
but where i have used the notifyAll
how can used and which situation we can used it
so have still some clearty

thanks
pp


View Tutorial          By: pp at 2009-06-29 06:12:13
7. View Comment

notify does NOT wake up the first thread waiting. it wakes up an abitrary thread waiting. notifyAll is almost always better than notify. A thread woken up by wait still has to compete with all other threads that are trying to lock on the object.

cheers
Armin


View Tutorial          By: Armin at 2009-07-26 07:25:09
8. View Comment

good example need some more explanation on notify all

View Tutorial          By: prashant at 2009-09-08 19:29:54
9. View Comment

Good example...easy to read and understand...

View Tutorial          By: Codventure at 2009-09-11 00:07:06
10. View Comment

Its a nice article obviously. Can you put something about asserstion. Hope it will be such a nice tutorial like this.

View Tutorial          By: kowser at 2009-10-06 23:44:52
11. View Comment

Great article. The simple example used easily makes the concept clear.

View Tutorial          By: Nikhil at 2009-11-13 08:38:41
12. View Comment

Marvelous Explanation. The whole concept is clear to me now

View Tutorial          By: Rohit at 2009-12-01 19:43:14
13. View Comment

Excellent!!!!! Thanks

View Tutorial          By: nimbostratue at 2009-12-09 13:07:09
14. View Comment

Good.understand

View Tutorial          By: Selva at 2009-12-29 23:27:29
15. View Comment

Very nice and easy to understand, keep it up !!

Cheers.


View Tutorial          By: claudiu at 2010-02-07 06:12:30
16. View Comment

is there a way to notify a specific thread?

View Tutorial          By: bob at 2010-03-23 11:57:29
17. View Comment

Really a great article!
I have some questions/suggestions:
Shouldn't be the wait-calls be inside a loop to account for spurious wakeups? (see http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#wait())
Also, I would put the rest of the code after the wait() also into the try-block, because i wouldn't want it to be executed after an InterruptedException.


View Tutorial          By: ron at 2010-03-30 01:37:12
18. View Comment

Very good. I like this way. First provide quite wrong implementation and then correct it. Its really good example. Thanks!

View Tutorial          By: NJ at 2010-04-01 23:27:44
19. View Comment

Very cool one, thanks, got the concept clear

View Tutorial          By: black boot at 2010-04-18 08:20:20
20. View Comment

Does Wait() inside synchronized create a race condition?

View Tutorial          By: Aviator168 at 2010-04-21 16:02:06
21. View Comment

Nice article, Thank you

View Tutorial          By: kumar kasimala at 2010-04-26 21:09:25
22. View Comment

Very nice article.. thanks

View Tutorial          By: Basu at 2010-05-29 05:52:00
23. View Comment

I have one doubt regarding this code,
if the producer thread is already synchronized on 'this' how does the consumer can enter get method which is again synchronized on 'this'.
And also in general i want to know why is wait(),notify() and notifyAll() are there in Object class.


View Tutorial          By: Yellappa at 2010-06-11 05:49:15
24. View Comment

Hello,

your solution is kinda overkill.
When used correctly, notify and wait don't need workarounds such as valueSet.

Here's the improved version:
----------------------
package producer;

// A correct implementation of a producer and consumer.
class Q {
int n;

synchronized int get() {
try {
notify();
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
return n;
}

synchronized void put(int n) {
try {
notify();
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
System.out.println("Put: " + n);
}
}

public class Producer implements Runnable {
Q q;

Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}

public void run() {
int i = 0;
while (true) {
q.put(i++);
}
}
}

class Consumer implements Runnable {
Q q;

Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}

public void run() {
while (true) {
q.get();
}
}
}

class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}

-------------------------


View Tutorial          By: Hdm-Student at 2010-06-16 08:10:51
25. View Comment

Explanations and examples are more clear. I like it.

View Tutorial          By: Rajkumar S at 2010-07-12 22:28:40
26. View Comment

27: What happens if the producer and the customer enterin the wait at same time? Deadlock? I think no protection against deadlock.

View Tutorial          By: Spender at 2010-07-25 14:42:08
27. View Comment

Excellent Example to explain the functions

View Tutorial          By: manish at 2010-08-05 03:10:43
28. View Comment

Thanks mate !!!

-- Anish Sneh


View Tutorial          By: Anish Sneh at 2010-08-18 07:42:56
29. View Comment

Thank you ... was very helpfull indeed !!

View Tutorial          By: Avinav at 2011-02-09 15:46:37
30. View Comment

This program little hard to understand ..please give in simple !

View Tutorial          By: sarav at 2011-02-17 05:02:46
31. View Comment

Nice Article, but these concepts are pretty confusing and sometimes hard to implement.

Good attempt though.

Goldest


View Tutorial          By: Goldest at 2011-03-18 01:50:50
32. View Comment

nice article... got th topic clearly

View Tutorial          By: praba at 2011-05-09 23:29:26
33. View Comment

how to send data one pc to another with java programming????

View Tutorial          By: usman at 2011-05-14 01:31:31
34. View Comment

Thanks alot. Really great and simple example!

View Tutorial          By: leo at 2011-06-06 13:58:32
35. View Comment

Code indentation would help!...

View Tutorial          By: James at 2011-06-30 04:54:51
36. View Comment

yes 29 you are correct! 27's example is prone to a deadlock.

View Tutorial          By: sameendra at 2011-07-24 11:55:54
37. View Comment

why 27's example is prone to a deadlock ? when producer and customer enter waiting status at the same time ?

View Tutorial          By: kaka at 2011-08-14 00:59:41
38. View Comment

Thank you for such a article. It is extreamly nice article to clear the doubt of the Thread, with the help of producer and consumer

View Tutorial          By: Ravi at 2011-08-23 10:04:14
39. View Comment

I could not understand, anyone having an easier example with simple explanation then plz tell.....

View Tutorial          By: aatish at 2011-09-14 09:52:28
40. View Comment

why r there these methods in Object class not in Thread class?

View Tutorial          By: santosh at 2011-11-16 06:58:06
41. View Comment

hope this may help u

class product
{
int contents=0;
boolean available = false;
synchronized int get()
{
if(available==false)
try
{
wait();
}
catch(InterruptedException e)
{
System.out.println("InterruptException caught");
}

System.out.println("consume:"+contents);
System.out.println("hello");
available=false;
notifyAll();
return contents;
}
synchronized void put(int num)
{
if(available==true)
try
{
wait();
}
catch(InterruptedException e)
{
System.out.println("InterruptedException caught");
}
contents=num;
System.out.println("produce:"+contents);
System.out.println("Welcome");
notifyAll();
}
}
class producer extends Thread
{
product p;
producer(product p)
{
this.p=p;
this.start();
}
public void run()
{
int i=0;
p.put(++i);
}
}
class consumer extends Thread
{
product p;
consumer(product p)
{
this.p=p;
this.start();
}
public void run()
{
p.get();
}
}
public class interthreadcon
{
public static void main(String[] args)
{
product s = new product();
new producer(s);
new consumer(s);
}
}


View Tutorial          By: princess at 2011-11-30 12:11:57
42. View Comment

I have a question. So here I have a progress bar, but it seems to not move. I needed a way to wait sixty seconds before it added a number to the value, so I went to this. I have no idea how to use this, and thought I was using it correctly. The compiler seems to disagree. Here's my progress bar code:

//makes the progress bar
JProgressBar Bar = new JProgressBar(0, 15);
int a = 0;
while (a <15) {
a = a + 1;
Bar.wait(60000);
notify();
}
Bar.setValue(a);
Bar.setStringPainted(true);
Bar.setBounds(700, 75, 206, 40);
Bar.setBorder(BorderFactory.createRaisedBevelBorder());
contentPane.add( Bar );

what i'm focusing on is the while loop. inside that, the compiler is complaining about the wait line. Apparently I am using this wrong. How do I use it right?


View Tutorial          By: Nick at 2011-12-06 05:10:19
43. View Comment

Nice article. Really helpful in understanding the functionality & usage of wait(), notify() and notifyAll() methods.

View Tutorial          By: Sundar at 2011-12-18 11:15:07
44. View Comment

Excellent example Jagan. By the way I have a question.
isn't the synchronized get() and synchronized put(...) methods will cause deadlock? Should they be synchronized? Can you explain why they need to be synchronized??
Thanks


View Tutorial          By: Shrihas at 2012-01-07 14:12:48
45. View Comment

29. It is not a deadlock. What will actually happen is that consumer might start first and consume something, that has not been produced yet. That's why 27's code is not correct.

View Tutorial          By: Sasha at 2012-01-24 14:34:03
46. View Comment

Nice article .... Thank you...

View Tutorial          By: viswa at 2012-06-16 17:21:59
47. View Comment

Hi,
Even if the while loops (in Producer and Consumer's run method ) in 27's code is made limited to a certain cycle then also 27's code could result into a thread (any one of producer or consumer) waiting indefinitely or for a long time.
This would happen as notify() is not present before returns from put() and get() methods. So there are chances when one of the thread could lead to a forever waiting state.


View Tutorial          By: Pranay at 2012-09-19 19:08:45
48. View Comment

Great Article...thanks :)

View Tutorial          By: Paras Chawla at 2012-10-28 04:35:57
49. View Comment

clear concept explanation..

View Tutorial          By: ASHOK at 2013-01-16 07:31:35
50. View Comment

Unfortunatelly this a BAD example of to communicate between Threads. In general, it is a bad idea to use wait and notify to communicate between Threads ONLY relying on wait and notify. The reason is very simple: nothing guaranties that object waiting will receive the proper notification. In other words it might either :

A) receive notification sent from someone else and NOT Producer.

just add this in main method at the end
synchronized(q)
{
q.notify();
}

or

B) Consumer never receives the notification and hangs

just add in the main method:

synchonized(q)
{
...
// do something forever without releasing the lock on q
}

In general, communication between threads should be done either through Events and (synchronized) EventMulticasters or anchored around VERY protected (encapsulated) synchronized object with with wait and notify only called on that object. Even then there is a pssibkity of messing that object's monitor.


View Tutorial          By: Mladen Covic at 2013-03-28 15:08:04
51. View Comment

Dear !

Thanks for the article. Now I got the whole concept of inter-thread communication mechanism by using wait() and notify() methods.
Thanks again


View Tutorial          By: Mubasher at 2013-05-04 11:37:52
52. View Comment

Many Thanks.

View Tutorial          By: Kallol Samaddar at 2013-07-11 18:26:06
53. View Comment

Thanks lot tutor.

View Tutorial          By: veda murthy at 2013-08-01 09:33:43
54. View Comment

Nice Example. Gives very clear idea.

View Tutorial          By: Larsen at 2013-09-14 02:29:24
55. View Comment

Thank you!!!!!

View Tutorial          By: wsjonly at 2013-09-19 18:41:50
56. View Comment

it is possible to write any synchronisation program without using synchronised method.. if it is possible then plz send the producer consumer proble without using synchronised method... on myemail...plz

View Tutorial          By: shashi kant mishra at 2013-10-14 02:54:25
57. View Comment

Hi ,

Since both the methods in the code which implement the Q class are Synchronized.

The threads will never be able to access it concurrently.
So the wait() method will never be called explicitly.

pls Correct me if i am wrong.


View Tutorial          By: Chintan at 2013-11-21 03:42:32
58. View Comment

You are using "this" to start to the thread before constructor has completed. Isn't it a wrong practice to use incompletely initialize objects by letting them escape before constructor completes-
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}


View Tutorial          By: sumit at 2014-10-30 08:14:55
59. View Comment

Good One..

View Tutorial          By: Subhranil Mukherjee at 2015-03-11 07:22:18

Your name (required):


Your email(required, will not be shown to the public):


Your sites URL (optional):


Your comments:



More Tutorials by Jagan
Importing a Certificate for the CA example using keytool in Java
The if-then-else Statement in Java
WHERE Clauses in SQL
The TryCatchFinally Interface in JSP
assert() Function Example program in C
Guidelines for Struts Application Development
Using printf function in C
File Inclusion in C
Using Multiple Message Resource Bundles in Struts
While and For Loops in C
Arrays sample program in C
Controlling Page Navigation in JSF - Static and Dynamic Navigation
Using cout.fill() in C++
Types of Profiles in J2ME
DateField sample program in J2ME

More Tutorials in Java
Update contents of a file within a jar file
Tomcat and httpd configured in port 8080 and 80
Java File
Java String
Count number of vowels, consonants and digits in a String in Java
Reverse a number in Java
Student marks calculation program in Java
Handling Fractions in Java
Calculate gross salary in Java
Calculate average sale of the week in Java
Vector in Java - Sample Program
MultiLevel Inheritance sample in Java
Multiple Inheritance sample in Java
Java program using Method Overriding
Java program to check if user input is an even number

More Latest News
Most Viewed Articles (in Java )
How to use ArrayList in Java
Student marks calculation program in Java
Count number of vowels, consonants and digits in a String in Java
FileReader and FileWriter example program in Java
Execute system commands in a Java Program
Palindrome String in Java
Why java is important to the Internet
Calculate gross salary in Java
Vector example in Java
Read from a COM port using Java program
Tomcat and httpd configured in port 8080 and 80
The Unary Operators example in Java
right shift operator, >>, in Java
Integer: byte, short, int, and long data types in Java
XML and Java - Parsing XML using Java Tutorial
Most Emailed Articles (in Java)
Using Charts in JasperReports
Introducing Nested and Inner Classes
Tomcat and httpd configured in port 8080 and 80
List all the serial and parallel ports in your system using Java
What is Unicode?
FileReader and FileWriter example program in Java
FilenameFilter - sample program in Java
Basics of Inheritance in Java
Method Overloading (function overloading) in Java
while - Iteration in java
how to use boolean data type in Java
equals( ) Versus == in Java
J2EE Components
Increment and Decrement Operator
Read from a COM port using Java program