Ответ
Semaphore (семафор) — это синхронизатор, который ограничивает количество потоков, одновременно имеющих доступ к общему ресурсу или пулу ресурсов.
Основные сценарии использования:
- Ограничение пула соединений: Например, не более 10 одновременных подключений к базе данных или внешнему API.
- Управление доступом к аппаратным ресурсам: Ограничение числа потоков, использующих принтер или сетевое устройство.
- Реализация паттерна "Producer-Consumer" с ограниченным буфером.
Как это работает? Семафор инициализируется количеством "разрешений" (permits). Поток должен захватить (acquire()) разрешение перед доступом к ресурсу и освободить (release()) его после завершения работы.
Пример: Ограничение параллельных HTTP-запросов
import java.util.concurrent.Semaphore;
public class RateLimiter {
private final Semaphore semaphore = new Semaphore(3); // Макс 3 параллельных запроса
public void makeHttpRequest(String url) {
try {
semaphore.acquire(); // Ждем, если уже 3 потока работают
System.out.println(Thread.currentThread().getName() + " делает запрос к " + url);
// Имитация HTTP-запроса
Thread.sleep(1000 + (int)(Math.random() * 2000));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release(); // Освобождаем слот для другого потока
System.out.println(Thread.currentThread().getName() + " завершил запрос.");
}
}
public static void main(String[] args) {
RateLimiter limiter = new RateLimiter();
// Запускаем 10 потоков, но одновременно будут работать не более 3
for (int i = 0; i < 10; i++) {
new Thread(() -> limiter.makeHttpRequest("api.example.com/data")).start();
}
}
}
Ключевые методы: acquire(), release(), tryAcquire() (неблокирующий), availablePermits().