synchronized
TL;DR
synchronizedis a keyword used to control access to a shared resource by multiple threads.- It prevents Race Conditions by ensuring that only one thread can execute the synchronized code block at a time.
- It achieves this by acquiring an intrinsic lock (a monitor) on a specific object.
Concept
When multiple threads read and write to the same variable simultaneously, their instructions get interleaved, resulting in corrupted data (a Race Condition).
To fix this, you must define a Critical Section—a block of code that must be executed atomically. The synchronized keyword acts as a locked door. When Thread A reaches the synchronized block, it “acquires the lock” on an object, locks the door, and goes inside. If Thread B arrives, it sees the door is locked and enters a BLOCKED state. When Thread A finishes, it unlocks the door, allowing Thread B to enter.
Types of Synchronization
- Synchronized Instance Method: Locks the current instance (
this). - Synchronized Static Method: Locks the Class object (
MyClass.class). - Synchronized Block: Locks a specific, explicitly defined object.
Examples
class BankAccount {
private int balance = 100;
// The lock is 'this' instance of BankAccount
public synchronized void withdraw(int amount) {
if (balance >= amount) {
System.out.println(Thread.currentThread().getName() + " is withdrawing...");
balance -= amount;
System.out.println("Remaining Balance: " + balance);
} else {
System.out.println("Insufficient funds for " + Thread.currentThread().getName());
}
}
// Using a synchronized block (More efficient, locks smaller scope)
public void deposit(int amount) {
System.out.println("Non-critical code executed by multiple threads concurrently...");
synchronized (this) {
balance += amount;
}
}
}
Interview Questions
Q: Is synchronized reentrant?
A: Yes. If a thread already holds the lock on an object, it can enter other synchronized blocks or methods that require the exact same lock without blocking itself. This prevents a thread from deadlocking itself when a synchronized method calls another synchronized method in the same class.
Q: What is the performance impact of synchronized?
A: Synchronization has a significant performance cost. It restricts multithreading to single-threading for that specific block of code, eliminating the benefits of concurrency. Furthermore, acquiring and releasing locks requires OS-level coordination. Therefore, you should always keep synchronized blocks as incredibly small as possible (synchronizing only the specific lines that touch shared memory, rather than the entire method).