Продолжаем устранять пробелы в многопоточке Java. Сегодня рассмотрим Semaphore и CountDownLatch.
Semaphore
Semaphore используется для управления доступом к ограниченному ресурсу, который может одновременно использоваться только определенным числом потоков. Это полезно для реализации пула ресурсов, например, подключения к базе данных, файловых дескрипторов и других ограниченных ресурсов.
Основные методы Semaphore
acquire(): Захватывает разрешение (пермит). Если разрешений нет, поток блокируется до тех пор, пока одно из них не станет доступным.
acquire(int permits): Захватывает указанное количество разрешений. Если их недостаточно, поток блокируется.
release(): Освобождает разрешение, увеличивая количество доступных разрешений на 1.
release(int permits): Освобождает указанное количество разрешений.
availablePermits(): Возвращает количество доступных разрешений.
tryAcquire(): Пытается захватить разрешение. Возвращает true, если удалось получить разрешение, иначе false.
tryAcquire(int permits, long timeout, TimeUnit unit): Пытается получить разрешения с указанным временем ожидания.
isFair(): Проверяет, использует ли семафор справедливый порядок захвата разрешений (FIFO).
Типы Semaphore
Несправедливый (non-fair): Потоки получают доступ в произвольном порядке (по умолчанию).
Справедливый (fair): Потоки получают доступ в порядке очереди (FIFO).
Пример использования Semaphore
Результат:
В каждый момент времени только 2 потока выполняют свою работу.
Остальные ждут освобождения разрешения.
Нюансы Semaphore
Справедливость (fair vs non-fair):
Несправедливый семафор быстрее, но поток может быть отложен, даже если он ожидает дольше других.
Справедливый семафор обеспечивает порядок очереди, но имеет больше накладных расходов.
Deadlock (взаимная блокировка):
Если поток забывает вызвать release() после acquire(), это приведет к "утечке" разрешений.
Пул ресурсов:
Часто используется для ограничения числа потоков, работающих с одним и тем же ресурсом.
#Java #Training #Multithreading #Semaphore
Semaphore
Semaphore используется для управления доступом к ограниченному ресурсу, который может одновременно использоваться только определенным числом потоков. Это полезно для реализации пула ресурсов, например, подключения к базе данных, файловых дескрипторов и других ограниченных ресурсов.
Основные методы Semaphore
acquire(): Захватывает разрешение (пермит). Если разрешений нет, поток блокируется до тех пор, пока одно из них не станет доступным.
acquire(int permits): Захватывает указанное количество разрешений. Если их недостаточно, поток блокируется.
release(): Освобождает разрешение, увеличивая количество доступных разрешений на 1.
release(int permits): Освобождает указанное количество разрешений.
availablePermits(): Возвращает количество доступных разрешений.
tryAcquire(): Пытается захватить разрешение. Возвращает true, если удалось получить разрешение, иначе false.
tryAcquire(int permits, long timeout, TimeUnit unit): Пытается получить разрешения с указанным временем ожидания.
isFair(): Проверяет, использует ли семафор справедливый порядок захвата разрешений (FIFO).
Типы Semaphore
Несправедливый (non-fair): Потоки получают доступ в произвольном порядке (по умолчанию).
Справедливый (fair): Потоки получают доступ в порядке очереди (FIFO).
Пример использования Semaphore
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
// Семафор с 2 разрешениями
Semaphore semaphore = new Semaphore(2);
// Пул из 5 потоков
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
final int threadId = i;
executor.submit(() -> {
try {
System.out.println("Thread " + threadId + " is waiting for permit...");
semaphore.acquire(); // Получаем разрешение
System.out.println("Thread " + threadId + " acquired permit.");
Thread.sleep(2000); // Имитируем использование ресурса
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
System.out.println("Thread " + threadId + " released permit.");
semaphore.release(); // Освобождаем разрешение
}
});
}
executor.shutdown();
}
}
Результат:
В каждый момент времени только 2 потока выполняют свою работу.
Остальные ждут освобождения разрешения.
Нюансы Semaphore
Справедливость (fair vs non-fair):
Несправедливый семафор быстрее, но поток может быть отложен, даже если он ожидает дольше других.
Справедливый семафор обеспечивает порядок очереди, но имеет больше накладных расходов.
Deadlock (взаимная блокировка):
Если поток забывает вызвать release() после acquire(), это приведет к "утечке" разрешений.
Пул ресурсов:
Часто используется для ограничения числа потоков, работающих с одним и тем же ресурсом.
#Java #Training #Multithreading #Semaphore