Gymterview
middle

На каком объекте происходит синхронизация при вызове 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 метод одного класса выполняться одновременно?» Ответ – да, могут, потому что используются разные мониторы. Это важно для понимания архитектуры блокировок.