К каким конструкциям в Java можно применить ключевое слово synchronized?

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

Ответ

Ключевое слово synchronized в Java применяется для синхронизации доступа к общим ресурсам в многопоточной среде. Его можно использовать в двух контекстах:

1. Синхронизированные методы:

  • Методы экземпляра: Блокируют монитор объекта (this), на котором вызван метод.
    public synchronized void instanceMethod() {
        // Критическая секция. Монитор: this
    }
  • Статические методы: Блокируют монитор объекта класса (Class<?>).
    public static synchronized void staticMethod() {
        // Критическая секция. Монитор: MyClass.class
    }

2. Синхронизированные блоки: Позволяют синхронизировать не весь метод, а только его часть, используя явно указанный объект-монитор.

public void method() {
    // Несинхронизированный код
    synchronized (lockObject) { // lockObject — любой объект, используемый как монитор
        // Критическая секция. Монитор: lockObject
    }
    // Другой несинхронизированный код
}

Важные детали:

  • synchronized нельзя применить к переменным, полям класса или блокам инициализации напрямую.
  • Каждый объект в Java имеет связанный с ним монитор (intrinsic lock), который и используется synchronized.
  • Избыточная или крупная синхронизация (synchronized на больших методах) может стать узким местом производительности. В современных приложениях часто предпочитают более гибкие механизмы из пакета java.util.concurrent.