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

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

Ответ

Монитором (встроенной блокировкой) для нестатического synchronized метода является экземпляр объекта (this), у которого этот метод вызывается.

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

  • Каждый объект в Java имеет связанный с ним монитор (intrinsic lock).
  • Когда поток входит в synchronized метод, он захватывает монитор этого конкретного объекта.
  • Другие потоки будут заблокированы при попытке войти в любой synchronized метод (или synchronized(this) блок) этого же экземпляра, пока первый поток не освободит монитор.

Пример:

public class BankAccount {
    private int balance;

    // Монитором для этого метода служит экземпляр BankAccount
    public synchronized void deposit(int amount) {
        balance += amount;
    }

    public synchronized void withdraw(int amount) {
        if (balance >= amount) {
            balance -= amount;
        }
    }
}

BankAccount account1 = new BankAccount();
BankAccount account2 = new BankAccount();

// Поток 1: Захватывает монитор account1
account1.deposit(100);

// Поток 2: Может работать с account2 параллельно (это другой монитор).
account2.withdraw(50);

// Поток 3: Будет ждать, если попытается вызвать account1.withdraw() пока Поток 1 не выйдет из deposit().

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

public void deposit(int amount) {
    synchronized(this) { // Явное указание на монитор объекта
        balance += amount;
    }
}