Что выступает монитором для статического synchronized метода в Java?

«Что выступает монитором для статического synchronized метода в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Монитором для статического synchronized метода является объект класса Class, соответствующий классу, в котором объявлен метод.

Ключевые моменты:

  • В JVM каждый загруженный класс представлен объектом типа java.lang.Class.
  • Статические synchronized методы используют монитор этого объекта Class, а не монитор какого-либо экземпляра.
  • Это означает, что блокировка распространяется на все статические synchronized методы класса и все synchronized(ClassName.class) блоки для всех экземпляров приложения.

Пример:

public class Logger {
    private static List<String> logEntries = new ArrayList<>();

    // Монитором является Logger.class
    public static synchronized void log(String message) {
        logEntries.add(message);
    }

    // Этот метод использует ТОТ ЖЕ монитор (Logger.class)
    public static synchronized void clearLog() {
        logEntries.clear();
    }
}

// В разных потоках:
Logger.log("Start"); // Поток 1 захватывает монитор Logger.class
// Поток 2 будет ждать здесь, если попытается вызвать Logger.clearLog()

Эквивалентная запись с явной блокировкой:

public static void log(String message) {
    synchronized(Logger.class) { // Явная блокировка по объекту Class
        logEntries.add(message);
    }
}

Важное отличие от нестатических методов:

  • Нестатический метод: synchronized → блокировка по this (экземпляру).
  • Статический метод: synchronized → блокировка по ClassName.class.

Это разделение предотвращает нежелательные блокировки между операциями над экземплярами и статическими данными.