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