简单介绍
我们以饭店为例, 假设饭店只有三个座位, 一开始三个座位都是空的. 这时如果同时来了三个客人, 服务员人允许他们进去用餐, 然后对外说暂无座位. 后来的客人必须在门口等待, 直到有客人离开. 这时, 如果有一个客人离开, 服务员告诉客人, 可以进来用餐, 如果又有客人离开, 则又可以进来客人用餐, 如此往复.
在这个饭店中, 座位是公共资源, 每个人好比一个线程, 服务员起的就是信号量的作用. 信号量是一个非负整数, 表示了当前公共资源的可用数目 (在上面的例子中可以用空闲的座位类比信号量), 当一个线程要使用公共资源时 (在上面的例子中可以用客人比线程), 首先要查看信号量, 如果信号量的值大于 1, 则将其减 1, 然后去占有公共资源. 如果信号量的值为 0, 则线程会将自己阻塞, 直到有其它线程释放公共资源.
1, 简单介绍 Semaphore
a, 可用来控制同时访问特定资源的线程数量, 以此来达到协调线程工作.
b, 维护了一个虚拟的资源池, 如果许可为 0 则线程阻塞等待, 直到许可大于 0 时又可以有机会获取许可了.
c, 内部也有公平锁, 非公平锁来访问资源的静态内部类.
2,Semaphore 方法
- a,public Semaphore(int permits);// 创建一个给定许可数量的信号量对象, 且默认以非公平锁方式获取资源
- b,public Semaphore(int permits, boolean fair);// 创建一个给定许可数量的信号量对象, 且是否公平方式由传入的 fair 布尔参数值决定
- c,public void acquire() ;// 从此信号量获取一个许可, 当许可数量小于零时, 则阻塞等待
- d,public void acquire(int permits) ;// 从此信号量获取 permits 个许可, 当许可数量小于零时, 则阻塞等待, 但是当阻塞等待的线程被唤醒后发现被中断过的话则会抛 InterruptedException 异常
e,public void acquireUninterruptibly(int permits) ; 从此信号量获取 permits 个许可, 当许可数量小于零时, 则阻塞等待, 但是当阻塞等待的线程被唤醒后发现被中断过的话则不会抛 InterruptedException 异常
f,public void release();// 释放一个许可
g,public void release(int permits); 释放 permits 个许可
以上只是列出主要方法名, 方法详细解释, Semaphore 类上面都有注释. 就不一一累出来了.
举一个简单例子, 帮助我们加深印象
- /**
- * @author shuliangzhao
- * @Title: SemaPhoreTest
- * @ProjectName design-parent
- * @Description: TODO
- * @date 2019/6/5 22:50
- */
- public class SemaPhoreTest {
- private Semaphore semaphore = new Semaphore(3);
- class TaskThread implements Runnable{
- private int id;
- public TaskThread(int id) {
- this.id = id;
- }
- @Override
- public void run() {
- try {
- semaphore.acquire();
- System.out.println("Thread" + id + "is working");
- Thread.sleep(2000);
- semaphore.release();
- System.out.println("Thread" + id + "is over");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- public static void main(String[] args) {
- SemaPhoreTest semaPhoreTest = new SemaPhoreTest();
- /*for (int i = 0;i<6;i++) {
- Thread thread = new Thread(semaPhoreTest.new TaskThread(i));
- thread.start();
- }*/
- ExecutorService executorService = Executors.newCachedThreadPool();// 同步队列线程
- executorService.submit(semaPhoreTest.new TaskThread(1));
- executorService.submit(semaPhoreTest.new TaskThread(2));
- executorService.submit(semaPhoreTest.new TaskThread(3));
- executorService.submit(semaPhoreTest.new TaskThread(4));
- executorService.submit(semaPhoreTest.new TaskThread(5));
- executorService.submit(semaPhoreTest.new TaskThread(6));
- executorService.submit(semaPhoreTest.new TaskThread(7));
- executorService.shutdown();
- }
- }
运行结果
来源: https://www.cnblogs.com/treeshu/p/11026065.html