闲谈一下 Semaphore

Semaphore 在项目中使用很少,直到我读了一个开源项目,原来 Semaphore 可以被恰当地使用的。

一、Semaphore 简介

Semaphore(信号量)是一种计数器,用于限制同时访问特定资源或执行某段代码的线程数量。

它内部维护了一个许可的数量,每当一个线程进入需要被保护的代码块时,就尝试获取一个许可或者多个;当离开这个代码块时,则释放该许可。

如果所有许可都被占用,那么新请求许可的线程将等待。

Semaphore信号量与 CountDownLatch 不同的是,它内部的计数器是递增的,并且在一开始初始化允许的最大值。

二、初识 Semaphore

第一次正式认识 Semaphore 还是在一款开源软件上。

项目地址:gitee.com/uzongn/java…(fork到自己的仓库了)

项目简单介绍: Aliyun LOG Java Producer 是一个易于使用且高度可配置的 Java 类库,专门为运行在大数据、高并发场景下的 Java 应用量身打造。

2.1 Semaphore 的用途

用于控制正在发送空间的大小,类似于限流。 在这个开源软件它是这么使用的。下面是参数说明:maxBlockMs 表示最大的可用空间

image.png
类的位置:com.aliyun.openservices.aliyun.log.producer.LogProducer

image.png

memoryController 用于控制当前机器中正在发送中的日志内存总大小。

com.aliyun.openservices.aliyun.log.producer.internals.LogAccumulator

image.png

在这段逻辑中, 由于发送的日志是并发的,为了防止发送占用内存过大, Semaphore 类型的变量 memoryController,用于控制正在发送的内存总大小。 这样避免过多的发送线程发送日志,导致内存溢出。

image.png

简而言之:限流,限制发送日志的内存占用量。

三、Semaphore 使用注意事项

Semaphore调用acquire()获取许可, try ... finallyfinally中释放许可。通常建议放在 finally 代码块中。

调用acquire()可能会进入等待,直到满足条件为止。也可以使用tryAcquire()指定等待时间:

另外:避免线程等待,可以设置最长等待时长。

获取许可不允许设置负数。

public boolean tryAcquire(int permits) {
    if (permits < 0) throw new IllegalArgumentException();
    return sync.nonfairTryAcquireShared(permits) >= 0;
}

四、应用场景

image.png

根据 Semaphore 的特性,可以围绕 “限流” 场景,进行合理的落地。(注意是虚拟机级别的,非分布式)

五、Semaphore 内部结构

Semaphore的核心在于其内部类Sync,它继承自AbstractQueuedSynchronizer(AQS),这是其核心。Sync类通过getState()setState(int newState)方法管理许可数量。

  • 非公平模式:NonfairSync类通过nonfairTryAcquireShared(int acquires)nonfairTryReleaseShared(int releases)方法实现许可的获取和释放,这种方式下,线程的调度可能不是公平的。
  • 公平模式:FairSync类通过tryAcquireShared(int acquires)tryReleaseShared(int releases)方法实现许可的获取和释放,这种方式下,线程调度是公平的,即按照线程等待的顺序来分配许可。

默认是:非公平模式

 public Semaphore(int permits) {
        sync = new NonfairSync(permits);
 }

公平策略: 看当前线程节点的前驱节点是否也在等待获取该资源,如果是则放弃获取的权限,然后加入 AQS 阻塞队列,否则就直接获取。

六、总结

Semaphore 跟 CountDownLatch 一样,都复用 AQS 的能力。 另外都使用for(;;) 自旋 ,compareAndSetState 对 state 进行安全操作

整体上而言,Semaphore 在使用限流上经常被其他工具所替代,比如 guava#Ratelimiter 限流工具。所以在使用上不多。感兴趣可以再深入挖掘。

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=21102,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?