На каком объекте происходит синхронизация при вызове static synchronized метода?
При вызове static synchronized метода синхронизация происходит на объекте Class<?> данного класса. Каждый загруженный класс в JVM имеет ровно один объект Class<?>, и именно он выступает монитором для всех статических синхронизированных методов этого класса.
Эквивалентные конструкции
Следующий static synchronized метод:
Пример
public class SomeClass {
public static synchronized void someMethod() {
// код
}
}
полностью эквивалентен:
Пример
public class SomeClass {
public static void someMethod() {
synchronized (SomeClass.class) {
// код
}
}
}
Ключевые следствия
| Аспект | Описание |
|---|---|
| Один монитор на класс | Все static synchronized методы одного класса разделяют один монитор – SomeClass.class |
| Независимость от экземпляров | Статическая и нестатическая синхронизация используют разные мониторы: Class<?> vs this |
| Параллельный доступ | static synchronized метод и обычный synchronized метод одного класса могут выполняться параллельно, т.к. захватывают разные мониторы |
| Создание экземпляров | Оператор new не требует захвата монитора, поэтому новые экземпляры можно создавать даже когда static synchronized метод выполняется |
Пример: независимость статического и нестатического мониторов
public class MonitorDemo {
// Монитор: MonitorDemo.class
public static synchronized void staticMethod() {
System.out.println("static: " + Thread.currentThread().getName());
try { Thread.sleep(2000); } catch (InterruptedException e) { }
}
// Монитор: this (конкретный экземпляр)
public synchronized void instanceMethod() {
System.out.println("instance: " + Thread.currentThread().getName());
try { Thread.sleep(2000); } catch (InterruptedException e) { }
}
public static void main(String[] args) {
MonitorDemo obj = new MonitorDemo();
// Эти два вызова выполнятся ПАРАЛЛЕЛЬНО -- разные мониторы
new Thread(MonitorDemo::staticMethod).start();
new Thread(obj::instanceMethod).start();
}
}
Аналогия из жизни. Представьте офис компании:
static synchronized– это замок на входной двери всего здания (один на всю компанию), а обычныйsynchronized– это замок на двери конкретного кабинета (у каждого сотрудника свой). Можно запереть кабинет, не блокируя вход в здание, и наоборот.
На собеседовании. Часто за этим вопросом следует подвопрос: «Могут ли
static synchronizedметод и обычныйsynchronizedметод одного класса выполняться одновременно?» Ответ – да, могут, потому что используются разные мониторы. Это важно для понимания архитектуры блокировок.