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).
Đánh đổi: 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.