Khác ở object nào đang giữ monitor.
- Method instance
synchronized→ khoá trênthis. Mỗi instance một lock riêng. - Method
static synchronized→ khoá trên đối tượngCounter.class. Một lock duy nhất cho toàn bộ class, dùng chung giữa mọi instance.
java
class Counter {
private int perInstance;
private static int shared;
synchronized void bumpInstance() { perInstance++; } // lock: this
static synchronized void bumpShared() { shared++; } // lock: Counter.class
}Hệ quả hay bị hỏi: hai loại lock này độc lập nhau. Một thread đang ở trong bumpInstance() không hề chặn thread khác vào bumpShared() — chúng giữ hai monitor khác nhau. Nên nếu dữ liệu static cũng bị đụng từ method instance, synchronized trên instance không bảo vệ được nó.
Quy tắc: lock phải cùng phạm vi với dữ liệu. Bảo vệ field instance thì khoá instance; bảo vệ field static thì khoá class. Tránh synchronized(this) ở API công khai — code bên ngoài có thể khoá cùng object đó và tạo tranh chấp ngoài kiểm soát; dùng một private final Object lock = new Object() riêng.