synchronized Keyword
The synchronized keyword in Java is used to control concurrent access to shared resources. It ensures that only one thread at a time executes a critical section of code protected by the same lock, thereby preventing race conditions and ensuring data consistency. This is a very high-frequency interview topic in Java multithreading.
What Does synchronized Do?
- Acquires a monitor lock before executing code
- Allows mutual exclusion
- Releases the lock automatically when execution exits
- Ensures visibility of shared data (happens-before guarantee)
Monitor Lock (Intrinsic Lock)
- Every Java object has a monitor (intrinsic) lock
- synchronized uses this lock internally
- A thread must own the lock to enter synchronized code
Ways to Use synchronized
1️⃣ Synchronized Instance Method
Locks the current object (this).
class Counter {
int count = 0;
synchronized void increment() {
count++;
}
}
✔ Only one thread per object can execute this method at a time
2️⃣ Synchronized Block (Recommended)
Locks a specific object and limits the critical section.
class Counter {
int count = 0;
void increment() {
synchronized (this) {
count++;
}
}
}
✔ Better performance
✔ Fine-grained locking
3️⃣ Synchronized Static Method
Locks the class-level lock.
class Counter {
static int count = 0;
static synchronized void increment() {
count++;
}
}
✔ Lock used: Counter.class
✔ Shared across all instances
Object Lock vs Class Lock (Interview Favorite)
| Usage | Lock Acquired |
|---|---|
| Instance synchronized method | this |
| Synchronized block | Specified object |
| Static synchronized method | ClassName.class |
How synchronized Works (Execution Flow)
- Thread requests lock
- If lock available → thread enters block/method
- Other threads are BLOCKED
- Thread exits synchronized code
- Lock is released automatically
Visibility Guarantee (Important)
- Changes made inside synchronized block
- Are visible to other threads after lock release
✔ Solves visibility issues
✔ Prevents stale reads
synchronized and Thread States
- Waiting for lock → BLOCKED
- Inside synchronized code → RUNNABLE
What synchronized Does NOT Do
- Does NOT guarantee fairness
- Does NOT prevent deadlocks
- Does NOT improve performance
- Does NOT replace good design
Common Mistakes
- Synchronizing entire methods unnecessarily
- Synchronizing on wrong object
- Using this as lock in public APIs
- Overusing synchronized causing performance issues
Best Practices (Production-Grade)
- Prefer synchronized blocks over methods
- Keep synchronized code minimal
- Avoid synchronizing on mutable/public objects
- Use private final lock objects if needed
private final Object lock = new Object();
synchronized (lock) {
// critical section
}
synchronized vs volatile (Quick Contrast)
| Aspect | synchronized | volatile |
|---|---|---|
| Mutual exclusion | ✔ Yes | ❌ No |
| Visibility | ✔ Yes | ✔ Yes |
| Atomicity | ✔ Yes | ❌ No |
| Performance | Slower | Faster |
Interview-Ready Answers
Short Answer
synchronized ensures that only one thread accesses a critical section at a time.
Detailed Answer
In Java, the synchronized keyword is used to acquire an intrinsic lock on an object or class before executing critical code. It prevents race conditions, ensures data consistency, and provides memory visibility guarantees by enforcing happens-before relationships.
Key Takeaway
synchronized protects shared data, not threads. Use it sparingly and precisely to achieve correctness without sacrificing performance.