Synchronization đảm bảo chỉ một thread vào critical section tại một thời điểm — ngăn race condition khi nhiều thread share state.
Keyword synchronized dùng intrinsic lock của object:
class Counter {
private final Object lock = new Object(); // lock object riêng — pattern khuyên dùng
private int count = 0;
public synchronized void inc() { count++; } // lock = this
public void incBlock() { synchronized (lock) { count++; } }
public static synchronized void incStatic() { /* lock = Counter.class */ }
}Vì sao phải sync count++? Compile thành 3 bytecode op (read → add → write). 2 thread overlap → lost update.
synchronized đảm bảo: mutual exclusion + memory visibility (happens-before).
Trade-off: cost lock + nguy cơ deadlock + giảm parallelism.
Quy tắc:
1. Lock càng nhỏ càng tốt.
2. Dùng private final Object lock riêng, không dùng this/String literal.
3. Cân nhắc alternative: AtomicInteger/AtomicReference (CAS, lock-free), ConcurrentHashMap, ReentrantLock (có tryLock/fairness), immutable object.
ReentrantLock (Java 5+) — có tryLock(timeout), fairness, Condition. Phải unlock() thủ công trong finally.
Dùng synchronized cho compound op (check-then-act) không có equivalent atomic. Không cần sync cho thread-local data hoặc immutable object.
Synchronization ensures only one thread enters a critical section at a time — preventing race conditions when threads share state.
The synchronized keyword uses an object's intrinsic lock:
class Counter {
private final Object lock = new Object(); // private final lock — recommended pattern
private int count = 0;
public synchronized void inc() { count++; } // lock = this
public void incBlock() { synchronized (lock) { count++; } }
public static synchronized void incStatic() { /* lock = Counter.class */ }
}Why sync count++? It compiles to 3 bytecode ops (read → add → write). Two threads can overlap → lost updates.
synchronized provides: mutual exclusion + memory visibility (happens-before).
Trade-offs: lock cost + deadlock risk + reduced parallelism.
Rules:
1. Lock as small as possible.
2. Use a private final Object lock, not this or a String literal.
3. Prefer alternatives: AtomicInteger/AtomicReference (CAS, lock-free), ConcurrentHashMap, ReentrantLock (with tryLock/fairness), immutable objects.
ReentrantLock (Java 5+) — provides tryLock(timeout), fairness, Condition. Must call unlock() manually in a finally.
Use synchronized for compound ops (check-then-act) with no atomic equivalent. No sync needed for thread-local data or immutable objects.