Synchronized Method vs Synchronized Block in Java — Granularity and Lock Object Tradeoffs
Fast recall
Quick revision
Core answer
this (instance method) or Class> (static method). A synchronized block lets you wrap a smaller subset of code and choose the lock object explicitly — usually a private final Object lock = new Object();. Prefer synchronized blocks in modern code for three reasons: smaller critical sections (higher throughput under contention), private lock objects (external callers can't accidentally synchronize on your public instance and deadlock you), and multiple locks per class (different fields guarded by different monitors). Synchronized methods are acceptable only for small classes with a single invariant where the whole method IS the critical section.Whether the candidate knows that synchronized method locks on `this` (or Class for static), understands why that's a problem (external code can acquire it), and prefers block form with private lock object
Not knowing that `synchronized` on a method locks on `this` — assuming it creates an invisible private lock. Synchronizing on `String` literals, `Boolean.TRUE`, or other interned/shared objects
Explain that `synchronized` on `this` exposes your lock to external code (any caller can `synchronized(yourObj) {...}` and block your methods), and that separate fields should be guarded by separate lock objects to allow independent access
Interview-ready guide
Interview answer
Both synchronized methods and blocks use Java's intrinsic monitor. The difference is what you lock on and how much code is inside the critical section.
Synchronized method
- The entire method body is locked
- Instance method locks on `this`
- Static method locks on `Class>`
- Convenient but coarse-grained
Synchronized block
- You wrap only the statements that need protection
- You choose the lock object explicitly
- Typically a `private final Object lock = new Object()`
Why I prefer the block form in production
Problem 1: Locking on `this` exposes your lock to external code
- Any caller with a reference to your object can write
synchronized(yourObj) { Thread.sleep(60_000); }and freeze everysynchronizedmethod on it - Frameworks, logging wrappers, test code — any of them can accidentally do this
- A private lock field is encapsulated and unreachable from outside
Problem 2: Coarse-grained locking
- If a class has ten synchronized methods, all ten serialize on
this - A read of field A blocks a write to unrelated field B
- With separate private lock objects per field group, they don't contend
Problem 3: Lock held during I/O
public synchronized void transfer()holds the lock for the entire method including slow logging, audit, and network calls- With a block, I shrink the critical section to just the balance update — throughput under contention goes up dramatically
Watch out for `static synchronized`
- Locks on
MyClass.class, notthis - Does NOT block instance-synchronized methods of the same class — they use different monitors
- The
Classobject is globally accessible; same external-lock problem - Prefer
private static final Object CLASS_LOCK = new Object()
Things you must never lock on
- String literals — interned, shared JVM-wide
- Boxed primitives like
Integer.valueOf(1)— cached singletons Boolean.TRUE/FALSE— singletons- Mutable fields — reassignment breaks exclusion
The right idiom every time
private final Object lock = new Object();
public void foo() {
synchronized (lock) { /* smallest critical section */ }
}Recommendation: Default to synchronized blocks with private final lock objects. Use synchronized methods only when the class is small with one invariant and the whole method truly IS the critical section. Never lock on this, Class, String literals, or boxed primitives. Mark guarded fields with @GuardedBy("lock") (from Error Prone) for documentation and static analysis. And for anything beyond simple mutual exclusion, look at ReentrantLock (tryLock, fairness, interruptibility) or the lock-free tools in java.util.concurrent.atomic.
Synchronized Method vs Synchronized Block in Java — Granularity and Lock Object Tradeoffs
Direct Answer
Both acquire Java's intrinsic monitor, but they differ in scope and lock object. A synchronized method locks the entire method body on this (instance method) or Class<?> (static method). A synchronized block lets you wrap a smaller subset of code and choose the lock object explicitly — usually a private final Object lock = new Object();. Prefer synchronized blocks in modern code for three reasons: smaller critical sections (higher throughput under contention), private lock objects (external callers can't accidentally synchronize on your public instance and deadlock you), and multiple locks per class (different fields guarded by different monitors). Synchronized methods are acceptable only for small classes with a single invariant where the whole method IS the critical section.
Common Mistakes & Pitfalls
Not knowing that synchronized on a method locks on this — assuming it creates an invisible private lock. Synchronizing on String literals, Boolean.TRUE, or other interned/shared objects
Check your understanding
Answer these without looking back at the article.
- Why can external code accidentally deadlock your synchronized methods?
- What bytecode does `synchronized` generate?
- Why is synchronizing on a `String` literal a bug?
- When would you still prefer synchronized method over block?
- How does `@GuardedBy` help document synchronization?
Related interview prep categories
2Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.