Semaphore

  Semaphore也叫信号量,在JDK1.5被引入,用来控制同时访问某个特定资源的操作数量,或者同时执行某个指定操作的数量。还可以用来实现某种资源池,或者对容器施加边界。

  Semaphore内部维护了一组虚拟的许可,许可的数量可以通过构造函数的参数指定。

  访问特定资源前,必须使用acquire方法获得许可,如果许可数量为0,该线程则一直阻塞,直到有可用许可。

  访问资源后,使用release释放许可。

  Semaphore和ReentrantLock类似,获取许可有公平策略和非公平许可策略,默认情况下使用非公平策略。

  当初始值为1时,可以用作互斥锁,并具备不可重入的加锁语义。

  Semaphore将AQS的同步状态用于保存当前可用许可的数量。

实现资源池:

  一个固定长度的资源池,当池为空时,请求资源会失败。

  使用Semaphore可以实现当池为空时,请求会阻塞,非空时解除阻塞。

  也可以使用Semaphore将任何一种容器变成有界阻塞容器。

 1 import java.util.concurrent.ExecutorService;
 2 import java.util.concurrent.Executors;
 3 import java.util.concurrent.Semaphore;
 4 
 5 
 6 public class SemaPhore {
 7     public static void main(String[] args) {
 8         // 线程池
 9         ExecutorService exec = Executors.newCachedThreadPool();
10         // 只能5个线程同时访问
11         final Semaphore semp = new Semaphore(5);
12         // 模拟20个客户端访问
13         for (int index = 0; index < 20; index++) {
14             final int NO = index;
15             Runnable run = new Runnable() {
16                 public void run() {
17                     try {
18                         // 获取许可
19                         semp.acquire();
20                         System.out.println("Accessing: " + NO);
21                         Thread.sleep((long) (Math.random() * 6000));
22                         // 访问完后,释放
23                         semp.release();
24                         //availablePermits()指还剩多少个许可
25                         System.out.println("-----------------" + semp.availablePermits()); 
26                     } catch (InterruptedException e) {
27                         e.printStackTrace();
28                     }
29                 }
30             };
31             exec.execute(run);
32         }
33         // 退出线程池
34         exec.shutdown();
35     }
36 }
原文地址:https://www.cnblogs.com/mengchunchen/p/9890076.html