Cả hai đều cho loại trừ lẫn nhau và đều reentrant. Khác ở mức độ điều khiển.
synchronized | ReentrantLock | |
|---|---|---|
| Nhả lock | tự động khi ra khỏi khối | phải unlock() trong finally |
| Thử lấy lock | không | tryLock(), tryLock(timeout) |
| Chờ có thể huỷ | không | lockInterruptibly() |
| Fairness | không cấu hình được | new ReentrantLock(true) |
| Nhiều hàng chờ | 1 wait-set | nhiều Condition |
java
private final ReentrantLock lock = new ReentrantLock();
if (lock.tryLock(200, TimeUnit.MILLISECONDS)) {
try { transfer(); }
finally { lock.unlock(); } // bắt buộc, nếu quên là treo vĩnh viễn
} else {
throw new BusyException(); // không chờ vô hạn
}Chọn thế nào: mặc định dùng synchronized — ngắn hơn, không thể quên nhả lock, và JVM tối ưu tốt (biased/thin lock).
Chuyển sang ReentrantLock khi cần một trong: timeout (tránh treo request), huỷ chờ bằng interrupt, fairness, hoặc nhiều Condition cho các hàng chờ khác nhau (vd producer/consumer với notFull/notEmpty).