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

В чем разница между семафором и монитором?

1.0 Junior🔥 151 комментариев
#Основы Java

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

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

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

# Разница между семафором и монитором

Основные различия

Семафор и монитор — это два разных примитива синхронизации, решающие задачи многопоточного программирования, но по-разному.

Семафор (Semaphore)

Семафор — это счётчик, управляющий доступом к ресурсу. Основные характеристики:

Semaphore semaphore = new Semaphore(2); // Разрешить доступ 2 потокам одновременно

try {
    semaphore.acquire(); // Уменьшить счётчик
    // Критическая секция
} finally {
    semaphore.release(); // Увеличить счётчик
}
  • Внутренний счётчик: начинает с начального значения (обычно 1 или N)
  • acquire(): уменьшает счётчик, ждёт если счётчик = 0
  • release(): увеличивает счётчик
  • Низкоуровневый примитив: можно вызвать release() из другого потока
  • Разные потоки: acquire() и release() могут выполняться разными потоками

Монитор (Monitor)

Монитор — это объект синхронизации, встроенный в Java через ключевое слово synchronized. Основные характеристики:

public synchronized void criticalMethod() {
    // Только один поток может быть здесь одновременно
}

// Или явно через synchronized блок
synchronized (object) {
    // Критическая секция
}
  • Встроен в объекты: каждый Java объект имеет встроенный монитор (lock)
  • Автоматическое управление: lock и unlock выполняются автоматически
  • Взаимное исключение: только один поток может владеть монитором
  • Связан с объектом: wait() и notify() работают с конкретным монитором
  • Один поток: поток, который заблокировал монитор, должен его разблокировать

Ключевые различия

АспектСемафорМонитор
ТипСчётчикБлокировка
УправлениеРучное (acquire/release)Автоматическое (synchronized)
Начальное значениеN потоков1 поток
Разные потокиДа, release() из другого потокаНет, один поток должен unlock
Условные переменныеНет встроенныхwait()/notify() встроены
БезопасностьТребует осторожностиБолее безопасен в Java

Бинарный семафор vs Монитор

Бинарный семафор (значение 0 или 1) похож на монитор, но:

// Семафор — может быть разблокирован другим потоком
Semaphore binary = new Semaphore(1);
thread1.acquire(); // thread1 заблокировал
thread2.release(); // thread2 может разблокировать!

// Монитор — только тот же поток может разблокировать
synchronized(obj) {
    // thread1 заблокировал
    // thread2 НЕ может выйти отсюда
}

Когда что использовать

Используй семафор когда:

  • Нужно контролировать доступ к N ресурсам (пул потоков, соединений)
  • Нужна передача сигнала между потоками
  • Требуется гибкость (разблокировка из другого потока)

Используй монитор (synchronized) когда:

  • Нужна простая синхронизация методов
  • Нужны условные переменные (wait/notify)
  • Стандартный случай для Java

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

// Семафор: пул с ограничением
Semaphore connectionPool = new Semaphore(5);

thread1: connectionPool.acquire(); // ждёт, если нет свободных
thread1: // используем соединение
thread2: connectionPool.release(); // освобождает для другого потока

// Монитор: синхронизированный счётчик
synchronized (counter) {
    count++; // атомарно
}

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

В чем разница между семафором и монитором? | PrepBro