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

У каждого ли экземпляра есть свой mutex

2.0 Middle🔥 121 комментариев
#Docker, Kubernetes и DevOps

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

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

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

Есть ли у каждого экземпляра свой mutex в Java

Да, в Java каждый объект имеет встроенный монитор (mutex), который используется для синхронизации доступа к экземплярным данным. Это фундаментальная концепция многопоточности в Java.

Как работает монитор объекта

Когда вы используете ключевое слово synchronized, вы блокируете монитор конкретного объекта:

public class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }
}

Counter counter1 = new Counter();
Counter counter2 = new Counter();

В этом примере counter1 и counter2 имеют разные мониторы. Поток может одновременно выполнять increment() на counter1 и counter2, потому что они блокируют разные объекты.

Экземплярные vs классовые мониторы

Экземплярные мониторы:

  • Каждый объект создаёт свой монитор в памяти
  • Синхронизирует доступ к данным конкретного экземпляра
  • Несколько потоков могут параллельно работать с разными экземплярами
public class BankAccount {
    private double balance;

    public synchronized void deposit(double amount) {
        balance += amount;
    }
}

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

// Два потока могут одновременно вносить деньги на разные счета
Thread t1 = new Thread(() -> account1.deposit(100));
Thread t2 = new Thread(() -> account2.deposit(100));

Классовые мониторы:

  • Если метод объявлен как static synchronized, блокируется монитор класса
  • Все экземпляры класса используют один монитор
  • Потоки не могут работать параллельно с разными объектами
public class GlobalCounter {
    private static int total = 0;

    public static synchronized void increment() {
        total++;
    }
}

Явная синхронизация через ReentrantLock

Для более гибкого контроля используют ReentrantLock — явные мониторы:

public class SharedResource {
    private final ReentrantLock lock = new ReentrantLock();
    private int value = 0;

    public void setValue(int newValue) {
        lock.lock();
        try {
            value = newValue;
        } finally {
            lock.unlock();
        }
    }
}

SharedResource res1 = new SharedResource();
SharedResource res2 = new SharedResource();

// У каждого экземпляра свой ReentrantLock

Внутреннее устройство

Каждый объект в Java содержит заголовок объекта (object header), где хранится информация о мониторе:

  • Identificator блокировки
  • Счётчик повторной блокировки (для ReentrantLock)
  • Идентификатор потока-владельца
  • Состояние монитора (заблокирован/свободен)

Практический пример с проблемой

public class UnsafeCounter {
    private int count = 0;

    public void increment() {
        count++; // НЕ БЕЗОПАСНО! Без монитора
    }
}

// Правильно:
public class SafeCounter {
    private int count = 0;

    public synchronized void increment() {
        count++; // Каждый экземпляр защищен своим монитором
    }
}

Ответ на вопрос

Да, у каждого экземпляра есть свой встроенный монитор. Это позволяет несколько потокам параллельно работать с разными объектами без блокировки друг друга. Однако если вы используете static synchronized, все экземпляры класса блокируют один общий монитор класса, что снижает параллелизм.

У каждого ли экземпляра есть свой mutex | PrepBro