Multithreading
Synchronized Blocks
Learn to use block-level synchronization for fine-grained locking and better performance.
Interview: Commonly tests how to reduce locking overhead by shrinking lock scope, and how to lock on custom lock objects.
Unlike synchronized methods, a synchronized block allows targeting a specific block of code inside a method and choosing which object's monitor to lock on. This reduces lock contention and improves throughput.
Core Idea
Synchronizing only the lines that modify shared state limits the lock duration and scope.
Why It Matters
Avoiding synchronization on expensive operations (like I/O or network calls) prevents application bottlenecks.
Interview Lens
Expect optimization questions asking you to convert a synchronized method into a more performant synchronized block.
Fine-Grained Locking
In synchronized methods, the lock target is always this (or the class object). With synchronized blocks, you specify the target:
synchronized (lockObject) {
// Critical section code
}
This allows creating private lock objects (private final Object lock = new Object();). Locking on private objects prevents external clients from locking on your instance monitor, eliminating potential lock hijacking.
Code Walkthrough
This class demonstrates two independent operations protected by distinct private locks to allow parallel updates.
public class FineGrainedLockingDemo { private int count1 = 0; private int count2 = 0;private final Object lock1 = new Object(); private final Object lock2 = new Object();
public void increment1() { // Only synchronize the write operation synchronized (lock1) { count1++; } }
public void increment2() { synchronized (lock2) { count2++; } } }
Interview-Relevant Information
Q: Why is locking on local variables inside a method a bug?
Answer: Local variables are created on the stack for each thread invocation. Synchronizing on a local object (e.g. Object obj = new Object(); synchronized(obj) { ... }) locks on a brand new object unique to that thread. Since other threads get their own instances, mutual exclusion is completely bypassed.
Quick Checklist
How do you choose lock objects? Can you explain why fine-grained locking is better than method-level synchronization? If yes, you understand synchronized blocks.
Use Cases
Optimizing database connection pool locks where only queue operations need locking.
Preventing lock competition in classes managing multiple independent resources.
Common Mistakes
Synchronizing on non-final variables, because if the reference changes, different threads lock on different objects.
Locking on String literals or Boolean objects, which can cause deadlocks due to JVM JVM-wide caching (String pool/boolean caching).