Synchronization
1. Why Synchronization is Needed
Problem: Shared Data + Multiple Threads
class Counter {
int count = 0;
void increment() {
count++; // NOT thread-safe
}
}
Multi-threaded usage:
public static void main(String[] args) {
Counter c = new Counter();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) c.increment();
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) c.increment();
});
t1.start();
t2.start();
}
π Expected: 2000
π Reality: β unpredictable (like 1634, 1872β¦)
count++ is NOT atomic
It is actually:
- read count
- increment
- write back
π Two threads interfere β race condition
2. What is Synchronization?
Synchronization ensures only one thread accesses critical section at a time
3. synchronized Keyword
3.1 Method Level Synchronization
class Counter {
int count = 0;
synchronized void increment() {
count++;
}
}
3.2 Block Level Synchronization (Preferred)
class Counter {
int count = 0;
private final Object lock = new Object();
void increment() {
synchronized (lock) {
count++;
}
}
}
4. How Lock Works Internally
Thread enters synchronized block
β
Tries to acquire lock (monitor)
β
If available β enters
If not β goes to BLOCKED state
β
Executes critical section
β
Releases lock
5. Example with Lock Behavior
public static void main(String[] args) {
Object lock = new Object();
Thread t1 = new Thread(() -> {
synchronized (lock) {
System.out.println("T1 got lock");
try { Thread.sleep(3000); } catch (Exception e) {}
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
System.out.println("T2 got lock");
}
});
t1.start();
t2.start();
}
Result:
T1 got lock
(after 3 sec)
T2 got lock
6. Intrinsic Lock (Monitor Lock)
Every Java object has an internal lock (monitor).
synchronized(this) { }
means -> lock on current object
Without Sync (Bug)
Map<String, Integer> map = new HashMap<>();
// multiple threads updating
map.put("key", value); // unsafe
With Sync
Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>());
Key Points
- synchronized ensures:
- mutual exclusion
- visibility (JMM guarantee)
- Lock is always tied to an object
- Only one thread can hold a lock at a time