文章图片
[TOC]
一、什么是信号量
“信号量”在编程术语中使用单词semaphore,那什么是“信号量”?信号量就好比你家厨房入口架子上摆了三把锅。
文章图片
- 如果你的孩子热奶拿走一把,你的老婆热汤拿走一把,你的妈妈做菜拿走一把,你想煮面条就没有锅了。当你看到这种情况,你就不会进入厨房了,你处于等待状态。也就说厨房按照“锅的数量”作为信号量,只能容纳三个人(线程)。
- 当你的老婆热完汤之后,把锅重新放回架子上,你就可以去获得一个锅,你就可以进入厨房了。
- 计数器:计算信号量的使用情况,锅(信号)被使用一次减1,锅(信号)被还回一次加1
- 等待队列:当任务数量大于信号量数量上限的时候,任务进入等待队列
semaphore.acquire();
方法,就先得到一个信号“锅”(permit),遵循先来后到的原则。public Semaphore(int permits)
public Semaphore(int permits, boolean fair)
常用方法列表
方法名 | 作用 |
---|---|
acquire() | 获取一个permit,在获取到permit之前,线程处于阻塞状态 |
tryAcquire() | 尝试获取一个permit,获取成功返回true,否则返回false,不阻塞线程 |
tryAcquire(long timeout, TimeUnit unit) | 和tryAcquire()大部分实现一样,区别是提供超时设置,在超时时间范围内多次尝试,不阻塞线程。 |
availablePermits() | 获取目前剩余的信号permit的数量 |
release() | 释放一个permit,并唤醒一个等待信号permit的线程 |
hasQueuedThreads() | 返回值boolean类型,判断等待队列中是否存在等待线程 |
getQueueLength() | 获取等待队列中等待线程的数量 |
- 医院门诊排号器,三个在岗医生就是3个信号permit,当超出信号量数量的时候,想就诊就只能等待
- 停车场停车功能,n个车位就是n个信号permit,当超出信号量数量的时候,想停车也只能等待
public class TestKitchenSemaphore {//信号量-3把锅
privatestatic Semaphore threeWoks = new Semaphore(3);
public static void main(String[] args) throws InterruptedException {//模拟5个人抢占3把锅的场景
for(int i=0;
i < 5;
i++){
Thread.sleep(1000);
//模拟进入厨房的先后顺序,存在时间间隔new Thread(() -> {
try {
threeWoks.acquire();
//获取一个permit,信号量计数器减1
System.out.println(Thread.currentThread().getName()
+ "拿走了一把锅,还剩" + threeWoks.availablePermits() + "把锅");
Thread.sleep(new Random().nextInt(5000));
//模拟使用锅的时长threeWoks.release();
//释放permit,信号量计数器加1
System.out.println(Thread.currentThread().getName()
+ "还回一把锅,还剩" + threeWoks.availablePermits() + "把锅");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
上文代码的输出如下,我们可以看到每acquire一次信号量减1,每release一次信号量加1。信号量的上限是3,下限是0。当达到上限的时候,只有等先占据锅permit的线程释放,其他线程才能获取到锅permit。
Thread-0拿走了一把锅,还剩2把锅
Thread-1拿走了一把锅,还剩1把锅
Thread-2拿走了一把锅,还剩0把锅=> 备注:5个线程只能获取3个锅(上限)
Thread-1还回一把锅,还剩1把锅
Thread-3拿走了一把锅,还剩0把锅=> 备注:被还回才能被再次占用,不超过3
Thread-0还回一把锅,还剩1把锅
Thread-4拿走了一把锅,还剩0把锅=> 备注:被还回才能被再次占用,不超过3
Thread-2还回一把锅,还剩1把锅
Thread-3还回一把锅,还剩2把锅
Thread-4还回一把锅,还剩3把锅=> 备注:用完依次释放
欢迎关注我的博客,更多精品知识合集 本文转载注明出处(必须带连接,不能只转文字):字母哥博客 - zimug.com
【[java并发编程]基于信号量semaphore实现限流器】觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力!。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
- 《kafka修炼之道》
- 《手摸手教你学Spring Boot2.0》
- 《Spring Security-JWT-OAuth2一本通》
- 《实战前后端分离RBAC权限管理系统》
- 《实战SpringCloud微服务从青铜到王者》
推荐阅读
- Java 中的 BigDecimal,80% 的人竟然都用错了。。。
- 如何解密WebLogic控制台和Java密钥库密码()
- 用于生产JAVA应用程序系统的10个重要JVM选项
- java|如何查看mysql 的用户名和密码
- 秒懂 23 种设计模式!有点污,但真得秒啊...
- Java 序列化
- SSM框架|[超详细]SSM框架整合教程--入门级(图书增删改查)
- 中间件|Redis从入门到精通
- java|Java小白从入门到精通,Java零基础入门看这一篇就够了