🚀 Master Concurrency & Multithreading in Java!
Subscribe to Ram N Java for clean, visual, and beginner-friendly programming tutorials!
🔔 Subscribe NowWhat is the Monitor (Synchronization) Design Pattern?
The Monitor Pattern (also widely referred to as the Synchronization Design Pattern) is a fundamental concurrency pattern used to coordinate concurrent access to shared resources.
Core Definition: In concurrent programming, a monitor is an object or module intended to be used safely by more than one thread. Its defining characteristic is that its methods are executed with mutual exclusion. That is, at each point in time, at most one thread may be executing any of its methods.
The Problem: Shared Bank Account Race Condition
Imagine a joint bank account shared by two individuals, John (Thread A) and Tina (Thread B). The account has an initial balance of ₹1,000.
Both John and Tina attempt to withdraw ₹1,000 at the exact same moment:
- Thread A (John): Invokes
withdraw(1000). It checks the balance (₹1,000 ≥ ₹1,000) and passes validation. Before it updates the balance, the thread is preempted. - Thread B (Tina): Enters
withdraw(1000)simultaneously. Since the balance has not been deducted yet, it still sees ₹1,000. It passes the check, deducts ₹1,000, leaves the balance at ₹0, and dispenses the cash. - Thread A Resumes: Now Thread A continues execution and subtracts ₹1,000 from the current balance (0 − 1,000 = −₹1,000), dispensing another ₹1,000!
As a result, ₹2,000 was withdrawn from an account that only contained ₹1,000, causing data inconsistency and balance corruption due to a classic race condition.
The Solution: Applying the Monitor Pattern
To prevent multiple threads from entering the critical section simultaneously, we apply the Monitor pattern by synchronizing the method. In Java, this is achieved cleanly using the synchronized keyword:
public class BankAccount {
private int balance = 1000;
// Synchronized method enforces Mutual Exclusion
public synchronized boolean withdraw(int amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
return true; // Withdrawal successful
}
return false; // Insufficient balance or invalid amount
}
public synchronized int getBalance() {
return balance;
}
}
How Mutual Exclusion Resolves the Conflict
- When Thread A (John) calls
withdraw(), it acquires the monitor lock on theBankAccountinstance. - If Thread B (Tina) attempts to call
withdraw()at the same time, it is blocked and forced to wait until Thread A finishes. - Thread A completes the deduction, leaving the balance at ₹0, and releases the monitor lock.
- Thread B enters the method, checks the balance, finds insufficient funds (₹0 < ₹1,000), and is safely rejected.
Key Takeaways of the Monitor Pattern
- Guarantees Mutual Exclusion: Only one thread executes critical method logic at any given time.
- Prevents Race Conditions: Eliminates inconsistent state and corrupted business data in multithreaded environments.
- Built-in Java Support: Every object in Java has an intrinsic monitor lock used by
synchronizedblocks/methods andwait()/notify()mechanisms.
Recommended Concurrency & Architecture Tutorials:
Click here to watch in Youtube : https://www.youtube.com/watch?v=VWeyrtcFEI0
| Monitor or synchronization Design Pattern |
See also: