Java Thread: notify() and wait() examples

This article contains two code examples to demonstrate Java concurrency. They stand for very typical usage. By understanding them, you will have a better understanding about notify() and wait().

1. Some background knowledge

  1. synchronized keyword is used for exclusive accessing.
  2. To make a method synchronized, simply add the synchronized keyword to its declaration. Then no two invocations of synchronized methods on the same object can interleave with each other.
  3. Synchronized statements must specify the object that provides the intrinsic lock. When synchronized(this) is used, you have to avoid to synchronizing invocations of other objects' methods.
  4. 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( ).
  5. notify() wakes up the first thread that called wait() on the same object.

2. notify() and wait() - example 1

public class ThreadA {
    public static void main(String[] args){
        ThreadB b = new ThreadB();
        b.start();
 
        synchronized(b){
            try{
                System.out.println("Waiting for b to complete...");
                b.wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
 
            System.out.println("Total is: " + b.total);
        }
    }
}
 
class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
                total += i;
            }
            notify();
        }
    }
}

In the example above, an object, b, is synchronized. b completes the calculation before Main thread outputs its total value.

Output:

Waiting for b to complete...
Total is: 4950

If b is not synchonized like the code below:

public class ThreadA {
	public static void main(String[] args) {
		ThreadB b = new ThreadB();
		b.start();
 
		System.out.println("Total is: " + b.total);
 
	}
}
 
class ThreadB extends Thread {
	int total;
 
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			total += i;
		}
	}
}

The result would be 0, 10, etc. Because sum is not finished before it is used.

3. notify() and wait() - example 2

The second example is more complex, see the comments.

import java.util.Vector;
 
class Producer extends Thread {
 
    static final int MAXQUEUE = 5;
    private Vector messages = new Vector();
 
    @Override
    public void run() {
        try {
            while (true) {
                putMessage();
                //sleep(5000);
            }
        } catch (InterruptedException e) {
        }
    }
 
    private synchronized void putMessage() throws InterruptedException {
        while (messages.size() == MAXQUEUE) {
            wait();
        }
        messages.addElement(new java.util.Date().toString());
        System.out.println("put message");
        notify();
        //Later, when the necessary event happens, the thread that is running it calls notify() from a block synchronized on the same object.
    }
 
    // Called by Consumer
    public synchronized String getMessage() throws InterruptedException {
        notify();
        while (messages.size() == 0) {
            wait();//By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep.
        }
        String message = (String) messages.firstElement();
        messages.removeElement(message);
        return message;
    }
}
 
class Consumer extends Thread {
 
    Producer producer;
 
    Consumer(Producer p) {
        producer = p;
    }
 
    @Override
    public void run() {
        try {
            while (true) {
                String message = producer.getMessage();
                System.out.println("Got message: " + message);
                //sleep(200);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String args[]) {
        Producer producer = new Producer();
        producer.start();
        new Consumer(producer).start();
    }
}

A possible output sequence:

Got message: Fri Dec 02 21:37:21 EST 2011
put message
put message
put message
put message
put message
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
put message
put message
put message
put message
put message
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
Got message: Fri Dec 02 21:37:21 EST 2011
Category >> Concurrency  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>

  1. Java Experience on 2013-9-9

    Great code example.I want to add that while wait method is present in the object class, sleep method is present in the Thread class. This means that we can’t invoke sleep() method on any object. Some beginners don’t understand the locking mechanism used by wait and sleep methods in java

  2. Krzysiek on 2013-10-24

    If ThreadB be will aquire the lock before threadA then notify() will be called before wait() method. Then ThreadB will release the lock and we enter in synchronized block of ThreadA – wait() method will be called and program will hang cause notify() was already called before…

  3. Igor on 2013-11-7

    Totally agree, before call to b.wait() there should be a check that will verify whether ThreadB completed its execution.

  4. Igor on 2013-11-7

    Modified first program:

    public class ThreadA

    {

    public static void main(String[] args) throws InterruptedException

    {

    ThreadB b = new ThreadB();

    b.start();

    // Thread.sleep(500);

    if(!b.finished)

    synchronized (b)

    {

    try

    {

    System.out.println(“Waiting for b to complete…”);

    b.wait();

    }

    catch (InterruptedException e)

    {

    e.printStackTrace();

    }

    }

    System.out.println(“Total is: ” + b.total);

    }

    }

    class ThreadB extends Thread

    {

    int total;

    boolean finished;

    @Override

    public void run()

    {

    synchronized (this)

    {

    for (int i = 0; i < 100; i++)

    {

    total += i;

    }

    finished = true;

    notify();

    }

    }

    }

  5. maqsoodkhan on 2013-11-28

    I have doubt on threads can u tell me please when I have to use extends threads and implements and what is the difference between…

  6. Santhosh S on 2013-12-31

    Thank you for the information.

  7. Guest on 2014-1-10

    asdasd

  8. Guest on 2014-1-10

    Vishal

  9. Debjit Saha on 2014-1-15

    When you have to extend some other class and still use multithreading then you can use implements runnable as in java you wont be able to extend two classes at the same time.

  10. cadmy on 2014-1-27

    Sorry for damn question but why the result of the first example is 4950? How did it happen?

  11. ICF on 2014-2-18

    int i = 0; i < 100… this means the range of numbers [0,99]. If you add those numbers together you get 4950…. using the formula N(N+1)/2 where N is your largest number in this case 99
    99(99+1)/2 = 4950

  12. cadmy on 2014-2-19

    Thanks. I knew that the answer is a piece of cake

  13. hrkristiansen on 2014-2-28

    Example 1 is an absolutely hideous example of programming by coincidence: http://pragprog.com/the-pragmatic-programmer/extracts/coincidence

    It only works if the main thread gets the hold of the monitor for ‘b’ before ‘b’ itself does.

    The only way to assure this, is to make ThreadB implement Runnable (or use it as the one it already is) and then run it from a thread started from inside the ‘synchronized(b) { … }’ statement.

  14. Stech on 2014-3-1

    Easier way to see that is to devide the numbers to pairs in this way:
    (1+99)+(2+98)….+(49+51)+50=49*(100)+50. Just an anakdote i hope you like.

  15. snamiet on 2014-5-11

    Can anyone explain why this program is getting stopped..

    public class ThreadA {

    public static void main(String[] args){

    ThreadB b = new ThreadB();

    b.setName(“ThreadB”);

    System.out.println(Thread.currentThread().getName()+” 1 “+b.getState());

    b.start();

    try {

    b.join();

    } catch (InterruptedException e1) {

    // TODO Auto-generated catch block

    e1.printStackTrace();

    }

    System.out.println(Thread.currentThread().getName()+” 2 “+b.getState());

    synchronized(b){

    try{

    System.out.println(“Waiting for b to complete…”);

    System.out.println(Thread.currentThread().getName()+” 3 “+b.getState());

    b.wait();

    System.out.println(Thread.currentThread().getName()+” 4 “+b.getState());

    }catch(InterruptedException e){

    e.printStackTrace();

    }

    }

    // System.out.println(“C Total is: ” + c.total);

    System.out.println(“B Total is: ” + b.total);

    System.out.println(Thread.currentThread().getName()+” 5 “+b.getState());

    }

    }

    class ThreadB extends Thread{

    int total;

    @Override

    public void run(){

    synchronized(this){

    for(int i=0; i<100 ; i++){

    total += i;

    }

    this.notify();

    System.out.println(Thread.currentThread().getName()+" run 3 "+getState());

    }

    }

    }

    Output:

    main 1 NEW

    Thread-0 run 3 RUNNABLE

    main 2 TERMINATED

    Waiting for b to complete…

    main 3 TERMINATED

    —————————-
    Program is still running but it doesn't get end.
    Is it a deadlock?

  16. […] notify () and wait () […]

  17. […] notify () and wait () […]

  18. Amatya on 2014-6-10

    what is the name of second program..before psvm their should be a class name…

  19. Amatya on 2014-6-10

    what is the name of second program..before psvm their should be a class name.

  20. try this one on 2014-7-26

    package com.scjp.thread;

    import java.util.LinkedList;

    import java.util.List;

    import java.util.Queue;

    public class SychModification {

    public static void main(String[] args) {

    LinkedList linkedList = new LinkedList();

    AddItem addItem = new AddItem(linkedList, “Adding Thread”);

    AddItem addItem1 = new AddItem(linkedList, “Adding Thread1”);

    // AddItem addItem2 = new AddItem(linkedList, “Adding Thread2”);

    RemoveItem removeItem = new RemoveItem(linkedList,

    “Removing Item Thread”);

    removeItem.start();

    addItem.start();

    addItem1.start();

    // addItem2.start();

    }

    }

    class AddItem extends Thread {

    private List list;

    private static int count = 0;

    public AddItem(List list, String name) {

    super(name);

    this.list = list;

    }

    @Override

    public void run() {

    while (true) {

    try {

    synchronized (list) {

    System.out.println(“Adding value from ” + getName());

    list.add(“Add ITEM” + count++);

    list.notifyAll();

    }

    Thread.sleep(5000);

    } catch (InterruptedException ex) {

    ex.printStackTrace();

    }

    }

    }

    }

    class RemoveItem extends Thread {

    private List list;

    public RemoveItem(List list, String name) {

    super(name);

    this.list = list;

    }

    @Override

    public void run() {

    while (true) {

    try {

    synchronized (list) {

    list.wait();

    if(!list.isEmpty())

    System.out.println(((Queue) list).remove());

    System.out.println(list.size());

    }

    } catch (InterruptedException ex) {

    ex.printStackTrace();

    }

    }

    }

    }

  21. Ash on 2014-8-3

    “It only works if the main thread gets the hold of the monitor for ‘b’ before ‘b’ itself does.”
    I don’t see how this is true.
    b.start(); is starting b before main thread gets its lock
    b finishes its execution, gets into TERMINATED state and releases its lock
    main thread acquires b’s lock and gets into the synch’d block
    reads the value total and prints it out.

  22. ash on 2014-8-3

    nope – UR right on a closer look.

  23. […] 这里是一些同步代码的例子。 […]

  24. efttappingtechniques.com

    Java notify() and wait() examples

  25. […] Wait and Notify Example […]

  26. Ankit on 2014-12-15

    Looks fine form me ,
    main thread will start, then thread b will start and get the lock then completes its calculation. After that second block of synchronization will start and after printing “waiting for the thread b to complete….” it will call .wait() method to release the lock. Then again normal main thread will execute and prints the total.
    But I wanted a more complex example so that we can understand more . This is very simple example and not elaborating much

  27. hrkristiansen on 2014-12-15

    “b.wait()” will cause the current thread (i.e. the main thread) to wait until another thread has called one of the notify-methods of “b”. Since no other thread has access to “b”, other than “b” itself, the main thread will wait “forever”.

  28. Ai on 2014-12-16

    This example won’t work if notify() is called before wait() is called . If it is the case, then main thread will wait/block forever . To make sure wait() is called 1st then before b.start() , we issue wait() command . Am I right ?

  29. infoj on 2015-7-6

    call to wait() method should be with in a loop that checks the condition on which the thread is waiting. That’s a recommendation as per java docs to avoid a scenario known as spurious wakeup.

    Read more about it here – http://netjs.blogspot.com/2015/07/inter-thread-communiction-wait-notify-java-multi-thread.html

  30. vasanthjegathesan on 2015-9-16

    Quick hack: In that case, we can avoid wait “forever” with “b.wait(someTime)”.

  31. Ryan on 2015-10-1

    this is perfect for example #1 to understand more on wait()

  32. Darragh on 2015-10-22

    I agree. You should use b.join(); which will force the main thread to wait until the calculation is complete

  33. Vijay Shankar on 2015-10-23

    > Below is example of wait notify 1st customer is trying to withdrawal
    > money 2000 but account is having only 1000 Rs so wait for deposit,
    > once deposit is completed then customer will able to withdrawal
    > amount ..till deposit customer is waiting.

    package com.thread.example;

    class Cust{

    private int totalAmount=1000;

    public synchronized void withdrwl(int amount){
    System.out.println(“Total amount “+totalAmount +” withdrwling amount “+amount);
    if(this.totalAmount<amount){
    System.out.println("not enogh amount..waiting for deposite..");
    try{wait();}catch(Exception e){}
    }
    this.totalAmount-=amount;
    System.out.println("Withrawl successful..Remaining balance is "+totalAmount);

    }

    public synchronized void deposite(int amount){
    System.out.println("Depositing amount "+amount);
    this.totalAmount+=amount;
    System.out.println("deposit completed…and Now totalAmount is "+this.totalAmount);
    notify();
    }
    }

    class Depo implements Runnable{
    Cust c; int depo;
    Depo(Cust c, int depo){
    this.c=c;
    this.depo=depo;

    }

    @Override
    public void run() {
    c.deposite(depo);

    }

    }
    class Withdrawl implements Runnable{
    Cust c; int with;
    Withdrawl(Cust c, int with){
    this.c=c;
    this.with=with;

    }

    @Override
    public void run() {
    c.withdrwl(with);

    }

    }

    public class MainClass {

    public static void main(String[] args) {
    Cust c = new Cust();
    Thread w = new Thread(new Withdrawl(c, 2000));
    Thread d= new Thread(new Depo(c, 1000));
    w.start();
    d.start();

    }

    }

  34. Ries van Twisk on 2016-4-8

    Yes, you can try this example and once a while it will lock up.

  35. TSMX on 2016-6-15

    Can you please provide us an example of a correct Example 1 using Runnable?

  36. Sergey Zaytsev on 2016-7-22

    It looks like in example#2 code in getMessage() is broken… notify() method call is too early which’ll wake up thread(s) already in m’s waitSet ( which exactly is thread called putMessage() ). notify() should be places at the end of getMessage() method.

  37. Angelina Lawrence on 2016-8-18

    know how to you satisfy yahoo offer us an case in point of a accurate instance 1 by means of Runnable?

  38. Rahul on 2016-10-6

    Why we should always call wait method in loop

  39. pl4za on 2016-10-7

    My take on the first example. Added a sleep to simulate a notify too before the wait and a condition check to avoid thread lock:

    public class ThreadA {
    public static void main(String[] args){
    ThreadB b = new ThreadB();
    b.start();
    try {
    Thread.sleep(1000); // simulate a notify() before the wait()
    }
    catch (InterruptedException e) {

    }
    synchronized(b){
    try{
    System.out.println(“Waiting for b to complete…”);
    while (b.isAlive()) { //condition guarantees no thread lock occurs
    b.wait();
    }
    }catch(InterruptedException e){
    e.printStackTrace();
    }

    System.out.println(“Total is: ” + b.total);
    }
    }
    }

    class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
    synchronized(this){
    for(int i=0; i<100 ; i++){
    total += i;
    }
    notify();
    }
    }
    }

  40. Toma on 2017-5-28

    Please delete this shit so others won’t waste their time

  41. Juliekes on 2017-8-19

    Hello friends!
    I am an official representative of private company which deals with all kinds of written work (essay, coursework, dissertation, presentation, report, etc) in short time.
    We are ready to offer a free accomplishment of written work hoping for further cooperation and honest feedback about our service.
    Send your work topics to our email: [email protected]. This offer has limited quantities!!!

Leave a comment

*