Synchronization, Intrinsic Monitors & Deadlock Prevention
1Concept
The `synchronized` keyword enforces mutual exclusion using the intrinsic monitor lock of an object. Only one thread can hold an object's monitor at a time. Deadlock occurs when Thread 1 holds Lock A waiting for Lock B, while Thread 2 holds Lock B waiting for Lock A (circular wait). Deadlocks are prevented by strictly acquiring locks in global order.
2Architecture Diagram
Deadlock Circular Dependency:
[ Thread 1 ] --(Holds Lock A)--> [ Waiting for Lock B ]
^ |
| v
[ Waiting for Lock A ] <--(Holds Lock B)-- [ Thread 2 ]3Code Example
Core Java
public class SynchronizationDemo {
static class Counter {
private int count = 0;
// Synchronized method acquires 'this' monitor lock
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread t1 = new Thread(() -> { for (int i = 0; i < 1000; i++) counter.increment(); });
Thread t2 = new Thread(() -> { for (int i = 0; i < 1000; i++) counter.increment(); });
t1.start(); t2.start();
t1.join(); t2.join();
System.out.println("Thread-safe Synchronized Count: " + counter.getCount());
}
}4Expected Output
Thread-safe Synchronized Count: 2000
5Key Takeaways
- ✓Prefer synchronized blocks (`synchronized(lockObject)`) over synchronized methods to reduce critical section lock contention.
- ✓Always acquire multiple locks in a globally consistent order to prevent deadlocks.
- ✓Intrinsic locks are reentrant: a thread holding a lock can re-enter synchronized blocks guarded by that same lock.