Understanding Wait and Notify in Multithreading(continues)
Table of Contents
- Introduction
- Explanation of Wait and Notify in Multithreading
- Code Implementation
- Step-by-Step Code Explanation
- Pros and Cons of Wait and Notify
- Conclusion
Introduction
In multithreading, communication between threads is essential for maintaining proper synchronization.
In Java, the wait() and notify() methods are commonly used to allow threads to coordinate their actions.
This chapter discusses these methods in detail, offering insights into how they can be implemented for efficient thread synchronization.
The wait() method pauses the current thread until another thread signals it using notify() or notifyAll().
This allows for smoother and more efficient thread management.
Method | Purpose |
---|---|
wait() | Pauses the thread until notified |
notify() | Wakes up a single waiting thread |
notifyAll() | Wakes up all waiting threads |
The purpose of this article is to explain how to use these methods, what scenarios they are best suited for, and a step-by-step guide to implementation with an example.
Explanation of Wait and Notify in Multithreading
What is Wait and Notify?
- wait(): This method makes the current thread pause its execution and releases the lock it holds until another thread invokes notify() or notifyAll().
- notify(): This method wakes up one of the threads that called wait() on the same object. If multiple threads are waiting, one of them is selected arbitrarily.
- notifyAll(): Wakes up all the threads that are waiting on the object.
Use Cases
1. Producer-Consumer Problem: When a producer thread produces data and a consumer thread consumes it, wait() and notify() ensure that the producer doesn’t overflow the data buffer and the consumer doesn’t consume from an empty buffer.
2. Banking System: Managing deposits and withdrawals where one thread waits for a balance update while another deposits funds is a common application.
Code Implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
package org.studyeasy; public class Main { public static int balance = 0; synchronized public void withdraw(int amount) throws InterruptedException { if (balance <= 0) { System.out.println("Waiting for balance update after withdrawal of $" + amount); wait(); } balance = balance - amount; System.out.println("Current balance after withdrawal: $" + balance); } public void deposit(int amount) { synchronized(this) { System.out.println("Depositing $" + amount + " to the account."); balance = balance + amount; notify(); } } public static void main(String[] args) { Main main = new Main(); Thread thread1 = new Thread(new Runnable() { @Override public void run() { try { main.withdraw(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { main.deposit(2000); } }); thread1.start(); thread2.start(); } } |
Step-by-Step Code Explanation
- Defining Balance: The balance variable is initialized to 0, representing the starting balance in the account.
- Withdraw Method: The withdraw() method is synchronized, ensuring that only one thread can access it at a time. If the balance is zero or less, the method invokes wait(), causing the current thread to pause until a deposit is made.
- Deposit Method: The deposit() method adds funds to the balance. After depositing the amount, it calls notify() to wake up any waiting threads.
- Main Method: Two threads are created: one for withdrawing and one for depositing. The withdraw thread pauses until a deposit occurs.
Pros and Cons of Wait and Notify
Pros:
- Efficient Resource Management: Threads can pause their execution when waiting for resources, minimizing CPU usage.
- Thread Communication: Allows smooth communication between threads to ensure proper sequence of operations.
Cons:
- Risk of Deadlock: Incorrect synchronization can lead to deadlocks where two or more threads wait on each other indefinitely.
- Complexity: Managing thread states and ensuring proper locking requires careful design, making the code harder to debug.
Conclusion
The wait() and notify() methods are essential for managing inter-thread communication and synchronization.
They enable developers to write programs where threads cooperate effectively, particularly in scenarios like banking systems and resource management.