Топ-100Semaphore в Java - CodOrbits
LogoCodOrbits

Раздел: Многопоточность

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

Все разделы
Иконка Многопоточность

Semaphore в Java

Last updated: 6 мая 2025 г.

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

Пример программы:

1import java.io.*;
2import java.util.concurrent.Semaphore;
3
4public class SemaphoreExample {
5    public static void main(String[] args) {
6        Semaphore resources = new Semaphore(3); // три разрешения
7        // То есть одновременно могут выполняться только
8        // три потока, все остальные стоят в очереди пока
9        // одно из трех мест не освободится.
10        for (int i = 1; i < 10; i++) {
11            SomeThread t = new SomeThread();
12            t.setName("Thread " + i);
13            t.resources = resources;
14            t.start();
15        }
16    }
17}
18
19class SomeThread extends Thread {
20    Semaphore resources;
21
22    @Override
23    public void run() {
24        try {
25            // Поток занимает одно из трех разрешений
26            resources.acquire();
27            System.out.println(
28                Thread.currentThread().getName()
29                + " entered the resource"
30            );
31            Thread.sleep(1000);
32            System.out.println(
33                Thread.currentThread().getName()
34                + " left the resource"
35            );
36            resources.release(); // Поток покидает одно
37            // из трех разрешений, после этого оставленное
38            // разрешение сразу занимает другой поток,
39            // стоявший в очереди на занятие разрешения,
40            // поскольку не мог занять разрешение, так как
41            // все три были заняты другими потоками.
42        } catch (InterruptedException e) {}
43    }
44}

Вывод:

Из консоли видно, что одновременно выполняются только три потока.

Example

Программа выполняется в следующей последовательности:

Видим, что сначала выполняются только 1,2,3 поток.

Потом 1,2 поток завершают свое выполнение. И на их место стразу становятся 4,6 потоки, которые стояли в очереди.

Далее завершает свою работу 3 поток, и на его место сразу становиться 5 поток.

То есть, очевидно, что параллельно друг другу всё время работают только три потока.


Следующие уроки

ReentrantLock - гибкая альтернатива synchronized

11
мин.

Similar Articles Icon
Divider

Ожидание завершения потоков с помощью CountDownLatch

10
мин.

Similar Articles Icon
Divider

CyclicBarrier в Java

10
мин.

Similar Articles Icon