简介
信号量常常用于多线程的代码中,它维护了一个许可集合。提供同步机制来控制同时访问的个数。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 35
| 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
|