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

Для чего нужен монитор?

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

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

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

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

Для чего нужен монитор?

В контексте Java и многопоточного программирования, монитор — это фундаментальный механизм синхронизации для управления доступом к общим ресурсам в многопоточной среде.

Основные функции монитора

1. Обеспечение взаимного исключения (Mutual Exclusion) Монитор гарантирует, что только один поток в один момент времени может выполнять код внутри synchronized блока или метода. Это предотвращает race conditions и data corruption:

synchronized(object) {
    // Критическая секция — только один поток может быть здесь
    sharedVariable = 42;
}

2. Предоставление средств для синхронизации потоков Монитор позволяет потокам координировать свою работу через методы wait(), notify() и notifyAll():

public synchronized void produce() throws InterruptedException {
    while (isFull) {
        wait(); // Ждём, пока появится место
    }
    add(item);
    notifyAll(); // Уведомляем потребителей
}

3. Защита инвариантов объекта Монитор обеспечивает, что внутреннее состояние объекта остаётся консистентным при одновременном доступе из разных потоков. Это критично для правильности программы.

Как работает монитор в Java

Каждый объект в Java имеет встроенный монитор (lock). Когда поток входит в synchronized блок:

  1. Пытается захватить монитор объекта
  2. Если монитор свободен — захватывает его и выполняет код
  3. Если занят другим потоком — ждёт в очереди
  4. После выхода из блока — освобождает монитор

Пример правильного использования:

class Counter {
    private int count = 0;
    
    // Метод синхронизирован на this
    public synchronized void increment() {
        count++; // Только один поток может быть здесь
    }
    
    public synchronized int getCount() {
        return count;
    }
}

Реальный пример: Producer-Consumer Pattern

class Buffer {
    private final int[] items = new int[10];
    private int count = 0;
    
    public synchronized void put(int value) throws InterruptedException {
        while (count == items.length) {
            wait(); // Ждём, если буфер полный
        }
        items[count++] = value;
        notifyAll(); // Уведомляем потребителей
    }
    
    public synchronized int take() throws InterruptedException {
        while (count == 0) {
            wait(); // Ждём, если буфер пуст
        }
        int value = items[--count];
        notifyAll(); // Уведомляем производителей
        return value;
    }
}

Почему это важно

Без мониторов работа с многопоточностью была бы крайне сложной и подверженной ошибкам. Они предоставляют простой и надежный механизм для:

  • Исключения race conditions
  • Обеспечения visibility изменений между потоками
  • Координации работы несколько потоков

Мониторы — это основа всех высокоуровневых инструментов синхронизации в Java (ReentrantLock, CountDownLatch, Semaphore и т.д.).