← Назад к вопросам

Что будет выступать монитором, если Synchronized обозначен внутри метода?

2.0 Middle🔥 111 комментариев
#JVM и память#Многопоточность и асинхронность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Монитор при использовании synchronized внутри метода

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

1. Синхронизация нестатического метода

В этом случае монитором является текущий экземпляр объекта (this). Это означает, что все synchronized-методы одного и того же объекта блокируют один и тот же монитор — сам объект.

public class Counter {
    private int count =新闻0;
    
    // Монитор - this (текущий объект Counter)
    public synchronized void increment() {
        count++;
    }
    
    // Тот же монитор - this
    public synchronized void decrement() {
        count--;
    }
}

Что это значит на практике:

  • Если один поток выполняет increment(), другой поток не может войти ни в increment(), ни в decrement(), ни в любой другой synchronized-метод того же объекта
  • Но разные объекты Counter имеют разные мониторы, поэтому их synchronized-методы выполняются независимо

2. Синхронизация статического метода

Для статических методов монитором выступает объект класса (Class object), который представляет сам класс в JVM.

public class Config {
    private static int settings = 0;
    
    // Монитор - Config.class (объект класса Config)
    public static synchronized void updateSettings() {
        settings++;
    }
}

Особенности статической синхронизации:

  • Все synchronized-статические методы одного класса блокируют один и тот же монитор — объект класса
  • Это глобальная блокировка на уровне класса, а не объекта
  • Нестатический synchronized-метод и статический synchronized-метод одного класса используют разные мониторы, поэтому не блокируют друг друга

3. Эквивалентность с synchronized-блоками

Важно понимать, что synchronized-методы — это просто синтаксический сахар. Компилятор преобразует их в synchronized-блоки:

// Оригинальный synchronized-d метод
public synchronized void method() {
    // тело метода
}

// Эквивалент, который генерирует компилятор
public void method() {
    synchronized(this) {  // Монитор - this
        // тело метода
    }
}

// Для статического метода
public static synchronized void staticMethod() {
    // тело метода
}

// Эквивалент
public static void staticMethod() {
    synchronized(Config.class) {  // Монитор - класс
        // тело метода
    }
}

4. Критические последствия выбора монитора

Проблемы при использовании this как монитора:

  1. Избыточная блокировка: Все synchronized-методы объекта блокируют друг друга, даже если они работают с разными данными
  2. Публичность монитора: Любой код, имеющий ссылку на объект, может синхронизироваться на нём, вызывая неожиданные взаимоблокировки
  3. Наследование: synchronized-методы в родительском и дочернем классах используют тот же монитор (this)

Рекомендации по использованию:

public class Account {
    private final Object lock = new Object();  // Приватный монитор
    private double balance;
    
    public void deposit(double amount) {
        synchronized(lock) {  // Используем приватный монитор
            balance += amount;
        }
    }
    
    public void withdraw(double amount) {
        synchronized(lock) {  // Тот же приватный монитор
            balance -= amount;
        }
    }
}

5. Производительность и потокобезопасность

Выбор монитора влияет на: -( Гранулярность блокировки: synchronized-методы дают грубую блокировку (весь объект), тогда как synchronized.блоки с приватными мониторами позволяют более тонкую синхронизацию -( Взаимоблокировки: Использование this как монитора увеличивает риск взаимоблокировок, так как внешний код может синхронизироваться на том же объекте -( Производительность: Статические synchronized-методы создают глобальные блокировки, которые могут стать узким местом в многопоточных приложениях

Вывод

При использовании synchronized внутри метода:

  1. Для нестатических методов монитором выступает this — текущий объект
  2. Для статических методов монитором выступает Class object — объект класса

Это решение простое, но не всегда оптимальное. В современных многопоточных приложениях часто предпочитают использовать явные synchronized-блоки с приватными объектами-мониторами или более продвинутые механизмы из пакета java.util.concurrent.

Что будет выступать монитором, если Synchronized обозначен внутри метода? | PrepBro