JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

Java 中的 Semaphore 信号量使用方法

wys521 2024-11-06 20:34:23 精选教程 28 ℃ 0 评论

Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

Semaphore

Semaphore 有两个构造函数,参数为许可的个数 permits 和是否公平竞争 fair。通过 acquire 方法能够获得的许可个数为 permits,如果超过了这个个数,就需要等待。当一个线程 release 释放了一个许可后,fair 决定了正在等待的线程该由谁获取许可,如果是公平竞争则等待时间最长的线程获取,如果是非公平竞争则随机选择一个线程获取许可。不传 fair 的构造函数默认采用非公开竞争。

一个线程可以一次获取一个许可,也可以一次获取多个。 在 acquire 等待的过程中,如果线程被中断,acquire 会抛出中断异常,如果希望忽略中断继续等待可以调用 acquireUninterruptibly 方法。同时提供了 tryAcquire 方法尝试获取,获取失败返回 false,获取成功返回 true。tryAcquire 方法可以在获取不到时立即返回,也可以等待一段时间。需要注意的是,没有参数的 tryAcquire 方法在有许可可以获取的情况下,无论有没有线程在等待都能立即获取许可,即便是公平竞争也能立即获取。

使用示例

如下的示例中,测试方法 test 创建了多个线程,每个线程启动后都调用 acquire 方法,然后延时 5s 模仿业务耗时,最后调用 release 方法释放许可。

公平与非公平

在上述的示例中,如果 fair 传的是 true,则各个线程公平竞争,即按照等待时间的长短决定谁先获取许可。以 9 个线程竞争 3 个许可为例,执行结果如下,首选是线程 0、1、2 获取了许可,5s 后线程 3、4、5 获取了许可,最后是线程 6、7、8 获取许可,顺序基本上与创建线程并启动的先后顺序一致,也与各个线程等待的时间基本相符。

在上述的示例中,如果 fair 传的是 false,则各个线程非公平竞争,随机选取一个线程获取许可。以 9 个线程竞争 3 个许可为例,执行结果如下,首先是线程 0、1、3 获取了许可,5s 后线程 2、5、7 获取了许可,最后是线程 4、6、8 获取许可,与线程创建启动时间无关,也与线程等待时间无关。

分享学习笔记和技术总结,内容涉及 Java 进阶、虚拟机、MySQL、NoSQL、分布式计算、开源框架等多个领域。关注作者第一时间获取最新内容,公众号同名(阅读体验更佳)。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表