Java信号量-Semaphore

目录
  1. 简介
  2. 例子

简介

信号量常常用于多线程的代码中,它维护了一个许可集合。提供同步机制来控制同时访问的个数。java.util.concurrent包下的Semaphore可以很容易的进行信号量控制。

Java 中Semaphore提供了两中构造函数:

1
2
3
Semaphore(int permits);
Semaphore(int permits, boolean fair);
// permits表示最大的许可数量。fair表示是否公平模式(即true表示线程要按FIFO获取机会,无该字段的构造函数或该值为false则表示线程随机顺序获取许可)。

Semaphore提供acquire()、release()来获取和释放许可。程序可通过acquire()获取一个许可,没有则等待直到release()释放一个许可。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
// 只有5个线程能同时访问
final Semaphore semaphore = new Semaphore(5);
// 模拟10个客户端访问
for (int index = 0; index < 10; index++) {
final int NO = index;
Runnable run = () -> {
try {
// 获取许可
semaphore.acquire();
System.out.println("Accessing: " + NO);
TimeUnit.SECONDS.sleep(10);
// 释放许可
semaphore.release();
//availablePermits()返回当前有多少个许可可被获取
System.out.println("-----------------" + semaphore.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
}
};
exec.execute(run);
}
exec.shutdown();
}
}

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Accessing: 0
Accessing: 1
Accessing: 3
Accessing: 2
Accessing: 4
-----------------1
Accessing: 5
-----------------1
Accessing: 6
-----------------1
-----------------1
Accessing: 7
-----------------1
Accessing: 9
Accessing: 8
-----------------1
-----------------2
-----------------3
-----------------4
-----------------5