Phase 18 of 20 · Topic 18.3

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.