Search code examples
javamultithreadingwaitnotify

Issues with the placement of notify method


I was trying wait and notify methods. Notify method when put in run method does not work but when the same method is put in some other method it works.

public class NewProgram {
static int balance = 0;

public void withdraw(int amount) {
    synchronized(this)
    {
        if(balance== 0) {
        try{
            System.out.println("Waiting for deposit");
            wait();
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
        }
    }
        balance = balance - amount;
        System.out.println("Amount Withdrawn Successfully");   
}
public void deposit(int amount) {

    balance = balance + amount;
    System.out.println("Money Deposited Successfully");

    //  The Notify method here works
    //    synchronized(this) 
    //         {
    //             notify();
    //         }}

public static void main(String[] args) {

    NewProgram app = new NewProgram();
    Thread thread1 = new Thread (new Runnable(){

        @Override
        public void run(){
            app.withdraw(2000);
        }
    }); 
    
    thread1.start();

    Thread thread2 = new Thread(new Runnable(){

        @Override
        public void run() {
            try {
                Thread.sleep(5000);

            //  The Notify method here doesn't work
            //     synchronized(this) {
            //     notify();
            // }
                
            } catch (InterruptedException e) {
                
                e.printStackTrace();
            }
            
            app.deposit(3000);


            // The notify method from here doesn't work
            //synchronized(this) {
            //     notify();
            //}            
            System.out.println("Thread 2 ends");
        } 
    });
    thread2.start();
}}

So, here in this program withdraw method when balance is zero waits for deposit method for the money to be deposited. Then the lock on wait is removed and withdraw operations continue. This program runs perfectly when notify method is called in deposit method. But when notify is placed is run method of Thread 2 after calling the deposit method, the lock on wait is not removed, but the next statement Thread 2 ends gets executed and the program waits indefinitely. Please help me with this.


Solution

  • When you write notify(), it means exactly the same thing as if you wrote this.notify().

    Your deposit() method is an instance method of the NewProgram class. When you write notify() inside the deposit() method, you are notifying the NewProgram instance on which the deposit() method was called. Inside deposit(), this refers to a NewProgram instance.

    Your run() method for thread2 is not a NewProgram instance method. It is an instance method of the anonymous class that you defined when you wrote new Runnable(){ ... }. Inside the run() method, notify() (which really means this.notify()) is notifying an instance of the anonymous class, and not the NewProgram instance that is wait()ing in the withdraw() method in thread 1.