JUC并发工具类之Semaphore控制并发线程数
首先看看关于Semaphore的UML图:

从上图看,信号量的实现原理与锁类似,是基于AQS的;有公平与非公平之分。当初始的资源数为1时就退化为排它锁了,资源总数即state的初始值,在acquire里对state变量进行CAS减操作,减到0之后,线程阻塞;在release里对state变量进行CAS加操作。
下面简单示范Semaphore的使用:
1)

2)

3)
通过Semaphore的UML图可知,其使用AQS构建其阻塞类,在Java并发基础之AbstractQueuedSynchronizer(AQS) - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中大致介绍了AQS的模板方法,那么Semaphore是如何利用AQS构建阻塞类的呢?
1、创建信号量对象:
构造方法有两个,
,本文中案例使用第一个构造函数:

最终使用AQS中setState将参数传递给AQS中的state:Semaphore使用AQS类型的同步状态持有当期可用许可的数量。

2、获取acquire

Semaphore类中重写tryAcquireShared方法首先计算剩余许可的数量,如果没有足够的许可,会返回一个值表示获取操作失败。如果还有充足的许可剩余,tryAcquireShared会使用compareAndSetState尝试原子地递减许可的计数。如果成功(这意味着自从许可计数到最后一次看到后都没有被改变过),会返回一个值表示获取操作成功。返回值同样加入了是否运行其他共享获取尝试能否成功的信息,如果可以的话,其他等待的线程同样会解除阻塞。
注意tryAcquireShared方法内部使用无限循环,即无论是否有足够的许可数量,在相应获取操作时,该循环都会终止。尽管任何给定的compareAndSetState调用都可能由于与另一个线程的竞争而失败,但是这种场景它会重试。在重试过合理的次数后,两个终止条件中的一个会变成真。
3、释放release
类似地,跟踪到tryReleaseShared会递增许可计数,潜在地解除等待中的线程的阻塞并不断地重试直到成功地更新。tryReleaseShared的返回值表明释放操作释放可以解除其他线程的阻塞。

JUC并发工具类之Semaphore控制并发线程数的更多相关文章
- Java并发(十五):并发工具类——信号量Semaphore
先做总结: 1.Semaphore是什么? Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源. 把它比作是控制流量的红绿灯,比如XX马路要 ...
- 【Java并发工具类】Semaphore
前言 1965年,荷兰计算机科学家Dijkstra提出的信号量机制成为一种高效的进程同步机制.这之后的15年,信号量一直都是并发编程领域的终结者.1980年,管程被提出,成为继信号量之后的在并发编程领 ...
- Java多线程并发工具类-信号量Semaphore对象讲解
Java多线程并发工具类-Semaphore对象讲解 通过前面的学习,我们已经知道了Java多线程并发场景中使用比较多的两个工具类:做加法的CycliBarrier对象以及做减法的CountDownL ...
- Java并发工具类(四):线程间交换数据的Exchanger
简介 Exchanger(交换者)是一个用于线程间协作的工具类.Exchanger用于进行线程间的数据交换.它提供一个同步点,在这个同步点两个线程可以交换彼此的数据.这两个线程通过exchange方法 ...
- j.u.c系列(10)---之并发工具类:Semaphore
写在前面 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可:当信号量中有可用的许可 ...
- 1.3.4 并发工具类CountDownLatch/Semaphore/CyclicBarrier/FutureTask
CountDownLatch的2个用途: 1. 所有线程都到达相同的起跑线后,再一起开始跑(并非同时开始,而是队列中一个唤醒另一个)[此情况需到达起跑线后再调用await()等待其他线程] 2. 所有 ...
- Java并发—并发工具类
在JDK的并发包里提供了几个非常有用的并发工具类.CountDownLatch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程 ...
- JUC学习笔记--JUC中并发工具类
JUC中并发工具类 CountDownLatch CountDownLatch是我目前使用比较多的类,CountDownLatch初始化时会给定一个计数,然后每次调用countDown() 计数减1, ...
- JUC 常用4大并发工具类
什么是JUC? JUC就是java.util.concurrent包,这个包俗称JUC,里面都是解决并发问题的一些东西 该包的位置位于java下面的rt.jar包下面 4大常用并发工具类: Count ...
随机推荐
- PPT2010制作图片玻璃磨砂效果
原文链接: https://www.toutiao.com/i6488928834799272462/ 选择"插入"选项卡,"图像"功能组,"图片&q ...
- SSR远程密码修改
第一:输入passwd 第二:填入旧密码 ,随后会有新密码设置 第三:回车两次就行了.
- SYCOJ#111、吉祥物
题目-吉祥物 (shiyancang.cn) 1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,x; 4 int pos(i ...
- 网络协议学习笔记(四)传输层的UDP和TCP
概述 传输层里比较重要的两个协议,一个是 TCP,一个是 UDP.对于不从事底层开发的人员来讲,或者对于开发应用的人来讲,最常用的就是这两个协议.由于面试的时候,这两个协议经常会被放在一起问,因而我在 ...
- [学习分享] 在Windows操作系统下如何安装RMySQL包
最近在做股票的高频交易数据分析,需要用到数据库,而我只对MySQL比较熟悉,于是就安装了MySQL.当我安装好了MySQL后,正兴冲冲地准备安装RMySQL包时,问题来了:RMySQL包不支持wind ...
- conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
conda : 无法将"conda"项识别为 cmdlet.函数.脚本文件或可运行程序的名称.请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次. 解决办法: 没有添加系 ...
- centos下APUE 例程编译-解决报错与改写例子名字。
首先是编译生成libapue.a的库文件.按照readme的说法很简单改个目录make一下就好,但是在centos下还是有错.通过下面这篇博文<<UNIX环境高级编程中的apue.h错误& ...
- 搭建服务器之www-向外提供视频服务by html5 video标签
搭建好www服务器,主要目的有两个一个是试验下,另一个是想给女朋友个惊喜,给她个带视频的网页,嘿嘿当前测试下相应功能. 1,采用html5的视频功能:bideo标签. 源码如下: <!docty ...
- openSUSE修改grub来修复对win8的引导
前言:继上一次安装试用各版本linux发行版后,由于做项目将机器纯windows了一把,现在又想安回centos,各种挫折折腾两天玩残一个u盘日,其中包括自己本本的原装系统也崩了,各种泪奔,下面记录一 ...
- FilterChain过滤器链(Servlet)
在 Web 应用中,可以部署多个 Filter,若这些 Filter 都拦截同一目标资源,则它们就组成了一个 Filter 链(也称过滤器链).过滤器链中的每个过滤器负责特定的操作和任务,客户端的请求 ...