На что синхронизируется поток при использовании ключевого слова synchronized в Java?

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

Ответ

Ключевое слово synchronized обеспечивает синхронизацию по монитору (внутреннему замку) объекта.

Правила:

  1. Нестатический synchronized-метод блокирует монитор объекта this, на котором вызван метод.
  2. Статический synchronized-метод блокирует монитор объекта класса (ClassName.class).
  3. Synchronized-блок позволяет явно указать объект-монитор.

Примеры:

public class Counter {
    private int count = 0;
    private final Object customLock = new Object();

    // Синхронизация по монитору объекта 'this'
    public synchronized void increment() {
        count++;
    }

    // Синхронизация по монитору класса Counter.class
    public static synchronized void staticMethod() {
        // ...
    }

    // Синхронизация по произвольному объекту
    public void decrement() {
        synchronized (customLock) {
            count--;
        }
    }
}

Важно: Для корректной взаимной блокировки все конкурирующие потоки должны использовать один и тот же объект-монитор.