Master java skills

Wait, notify and notifyAll

Inter thread communication is required in context of synchronization. It is also known as inter-thread cooperaton.

Inter-thread cooperation is a way in which a thread pauses to run in a critical section for a period of time, and another thread is allowed to enter the same critical section. It is implemented by following 3 methods. All these methods are from Object class.

wait()

notify()

notifyAll()

wait() method

The wait() method is invoked on an object. When invoked, it causes current thread to release the lock on this object and wait. It has to wait until either another thread invokes notify() or notifyAll() method on the same object or specified amount of time has elapsed.

The current thread must own this object’s monitor, so it must be called from the synchronized method only otherwise it will throw exception.

Note -> wait() method must be called from within a synchronized context i.e. either from inside a synchronized block or method.

Method DeclarationDescription
public final void wait() throws InterruptedExceptionIt waits until object is notified.
public final void wait(long timeout) throws InterruptedExceptionIt waits for the specified amount of time.

notify() method

The notify() method wakes up a single thread that is waiting on the object’s monitor on which it is invoked. If any thread(s) are waiting on this object, one of them is selected and woken up. The selection is random and occurs at the discretion of the implementation of thread scheduler.

Method declaration

public final void notify()

notifyAll() method

notifyAll() method is used to wake up all the threads that are waiting on this object (object on which notifyAll() method is invoked). Then one of these awakened threads are given opportunity to run.

public final void notifyAll()

Example of wait()/ notify()/ notifyAll()

package com.sks;

public class Account {
	
	private int totalBalance = 5000;
	
	synchronized void withdrawMoney(int withdrawAmt) {
		String threadName = Thread.currentThread().getName();
		System.out.println(threadName + " : withdrawing " + withdrawAmt);

		while (this.totalBalance < withdrawAmt) {
			System.out.println(threadName + " : low balance. Deposit some money.");
			try {
				System.out.println(threadName + " : please deposit some money. I am waiting.");
				wait();
			} catch (Exception e) {
			}
		}
		totalBalance -= withdrawAmt;
		System.out.println(
				Thread.currentThread().getName() + " : withdrawl completed. Remaining Balance = " + totalBalance);
	}
	
	
	synchronized void depositMoney(int depositAmt) {
		String threadName = Thread.currentThread().getName();
		System.out.println(threadName + " : depositing " + depositAmt);
		totalBalance += depositAmt;
		System.out.println(
				threadName + " : deposit of money done. Total balance = " + totalBalance);
		System.out.println(threadName + " : You can withdraw now.");
		notifyAll();
	}

}
package com.sks;

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

		Account acct = new Account();

		Thread t1 = new Thread() {
			public void run() {
				acct.withdrawMoney(10000);
			}
		};

		t1.start();

		Thread.sleep(10000);

		Thread t2 = new Thread() {
			public void run() {
				acct.depositMoney(2000);
			}
		};

		t2.start();

		Thread.sleep(10000);

		Thread t3 = new Thread() {
			public void run() {
				acct.depositMoney(5000);
			}
		};

		t3.start();
	}
}
Output :
Thread-0 : withdrawing 10000
Thread-0 : low balance. Deposit some money.
Thread-0 : please deposit some money. I am waiting.
Thread-1 : depositing 2000
Thread-1 : deposit of money done. Total balance = 7000
Thread-1 : You can withdraw now.
Thread-0 : low balance. Deposit some money.
Thread-0 : please deposit some money. I am waiting.
Thread-2 : depositing 5000
Thread-2 : deposit of money done. Total balance = 12000
Thread-2 : You can withdraw now.
Thread-0 : withdrawl completed. Remaining Balance = 2000

Q. Why are wait(), notify() and notifyAll() methods defined in Object class

All these methods are defined in Object class because they work with the lock of the object. These methods control how lock is acquired or released which is associated with objects. This is the reason why these methods are defined in Object class rather than Thread class.

Difference between wait() and sleep() methods

wait() methodsleep() method
wait() method causes thread to release the lock on this object.sleep() method doesn’t cause thread to release the lock.
wait() is defined in Object classsleep() is defined in Thread class
wait() an instance methodsleep() is a static method
Threads are notified by notify() or notifyAll() methodsAfter the specified amount of time is over, sleep is completed and thread is awakened.