← Назад к вопросам
В чем разница между семафором и монитором?
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 с автоматическим управлением и условными переменными.