前言
多线程系列我们前面已经更新过多个章节,强烈建议小伙伴按照顺序学习:
Semaphore
称为信号量,是JUC中常见的一种工具类,该类使用起来比较简单,唯一的难点就是很多小伙伴们,对于信号量是什么很难理解,今天花Gie就来简单扼要的分析一波。
一、信号量是什么
- 生活场景举例
我国有很多污染比较严重的工厂,但是为了经济发展,又不能对其全部关停,因此国家就有一个折中的办法,每个工厂需要向环境保护行政主管部门申请排污许可证。只要拥有许可证的工厂才允许合法运作。但是每年的排污许可证又是有数量限制,不能允许过多的工厂申请,否则就无法起到环境污染程度的控制的。
- Java中信号量
在Java中,Semaphore
就是上面的排污许可证,也就是信号量。那我们有哪些场景会用到信号量呢,比如我们调用某个方法,而该方法内部是下载文件或大数据量处理操作,所以非常耗时,这个时候如果我们不对该方法加以限制,当一次性过多线程调用时,可能会拖垮整个服务,Semaphore
在这里就起到限制访问线程数量的作用。
二、Semaphore核心方法
Semaphore和CountDownLatch一样,内部维护一个核心属性sync,通过AQS的共享锁机制实现,这个后续会AQS会详细介绍
1 | arduino复制代码private final Sync sync; |
看一下Semaphore
的几个核心方法:
- Semaphore(int premits,boolean fair): 构造器方法。
permits
为信号量初始化数量,第二个参数fair
可以设置是否需要公平策略,如果传入true,那么Semaphore
会把等待的线程放入FIFO队列中,以便许可证被释放后,可以分配给等待时间最长的线程; - acquire(): 试图获取许可证,如果当前没有可用的,就会进入阻塞等待状态;
- tryAcquire(): 试图获取许可证,如果是否能够获取,都不会进入阻塞。
- tryAcquire(long timeout, TimeUnit unit): 和tryAcquire一样,只是多了一个超时时间,等待指定时间还获取不到许可证,就会停止等待;
- availablePermits: 获取可用许可证数量;
- release(): 释放一个许可证;
- release(int permits): 释放指定数量的许可证。
三、代码演示
现在创建100个线程,每个线程每次只获取(acquire(1)
)一个信号量,并将semaphore
数量初始化为3,,我们先看下代码,试想一下结果打印的会是什么呢。
1 | csharp复制代码public class SemaphoreDemo { |
打印结果如下:
可以清楚的看到,每次会有三个线程获取到信号量,只有信号量被释放后,其他线程才能继续获取。
代码过程图示如下:
- 初始化semaphore许可证数量为3;
- 线程1、线程2、线程3可以正常获取许可证,并方位服务;
- 线程4访问时由于许可证数量不足,进入阻塞;
- 当线程1释放许可证后,线程4使用acqire获取,正常访问服务。
上面我们演示了:使用semaphore.acquire()
来获取信号量,这时每个线程只会拿到一个信号量,但如果我们将代码改成acquire(2)
呢,这样会出现什么情况,这个时候会有几个线程能够同时执行呢,接下来继续代码演示一下。
1 | scss复制代码//只需要修改两处代码 |
结果如下:
其实这个是很容易理解的,因为一个线程一次获取两个许可证,但是只释放一个,所以许可证两轮之后不足以被其他线程再次获取,其他线程就会被阻塞。
四、注意事项
- 获取和释放的许可证数量必须一致,否则随着时间的推移,最后许可证数量不够用,会导致线程卡死。
Semaphore
设置是否公平性时,一般设置为true比较合理,因为Semaphore使用场景就是用在耗时较长的操作,如果被反复插队,线程就会持续陷入等待。- 获取和释放的许可证不要求为同一个线程,只要满足我们业务需要,可以由
A线程
获取许可证,让B线程
来释放。
总结
以上就是关于信号量的全部内容,总体看来,用法比较简单,再结合实际场景中许可证的栗子,我们掌握Semaphore
会容易很多,今天又是收获满满的一天,下一章说些什么呢,花哥会和大家分享另外一个有趣的知识点-Condition,我们下期见咯。
点关注,防走丢
以上就是本期全部内容,如有纰漏之处,请留言指教,非常感谢。我是花Gie ,有问题大家随时留言讨论 ,我们下期见🦮。
文章持续更新,可以微信搜一搜 【花哥编程】 第一时间阅读,并且可以获取面试资料学习视频等,有兴趣的小伙伴欢迎关注,一起学习,一起哈🐮🥃。
原创不易,你怎忍心白嫖,如果你觉得这篇文章对你有点用的话,感谢老铁为本文点个赞、评论或转发一下
,因为这将是我输出更多优质文章的动力,感谢!
本文转载自: 掘金