首先看看关于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控制并发线程数的更多相关文章

  1. Java并发(十五):并发工具类——信号量Semaphore

    先做总结: 1.Semaphore是什么? Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源. 把它比作是控制流量的红绿灯,比如XX马路要 ...

  2. 【Java并发工具类】Semaphore

    前言 1965年,荷兰计算机科学家Dijkstra提出的信号量机制成为一种高效的进程同步机制.这之后的15年,信号量一直都是并发编程领域的终结者.1980年,管程被提出,成为继信号量之后的在并发编程领 ...

  3. Java多线程并发工具类-信号量Semaphore对象讲解

    Java多线程并发工具类-Semaphore对象讲解 通过前面的学习,我们已经知道了Java多线程并发场景中使用比较多的两个工具类:做加法的CycliBarrier对象以及做减法的CountDownL ...

  4. Java并发工具类(四):线程间交换数据的Exchanger

    简介 Exchanger(交换者)是一个用于线程间协作的工具类.Exchanger用于进行线程间的数据交换.它提供一个同步点,在这个同步点两个线程可以交换彼此的数据.这两个线程通过exchange方法 ...

  5. j.u.c系列(10)---之并发工具类:Semaphore

    写在前面 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可:当信号量中有可用的许可 ...

  6. 1.3.4 并发工具类CountDownLatch/Semaphore/CyclicBarrier/FutureTask

    CountDownLatch的2个用途: 1. 所有线程都到达相同的起跑线后,再一起开始跑(并非同时开始,而是队列中一个唤醒另一个)[此情况需到达起跑线后再调用await()等待其他线程] 2. 所有 ...

  7. Java并发—并发工具类

    在JDK的并发包里提供了几个非常有用的并发工具类.CountDownLatch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程 ...

  8. JUC学习笔记--JUC中并发工具类

    JUC中并发工具类 CountDownLatch CountDownLatch是我目前使用比较多的类,CountDownLatch初始化时会给定一个计数,然后每次调用countDown() 计数减1, ...

  9. JUC 常用4大并发工具类

    什么是JUC? JUC就是java.util.concurrent包,这个包俗称JUC,里面都是解决并发问题的一些东西 该包的位置位于java下面的rt.jar包下面 4大常用并发工具类: Count ...

随机推荐

  1. 方法覆盖 和toString方法的作用

    当我们代码怎么编写的时候,在代码级别上构成了方法的覆盖呢? 两个类必须要有继承关系. 重写之后的方法和之前的方法具有:相同的返回值类型 相同的方法名 相同的形参列表 访问权限不能更高,只能更低 重写之 ...

  2. HDU 2044 一只小蜜蜂... (斐波那契数列)

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2044 题目分析:其实仔细读题就会发现其中的规律, 其中:这是一个典型的斐波那契数列. 代码如下: #i ...

  3. promise初体验,小白也能看懂

    promise出现的目的一为处理JavaScript里的异步,再就是避免回调地狱. promise有三种状态:pending/reslove/reject . pending就是未决,resolve可 ...

  4. 【PTA】6-1 **删除C程序中的注释 (31 分)

    请你编写一个函数,将C语言源程序中的注释全部删去. 函数原型 // 删除注释 void Pack(FILE *src, FILE *dst); 说明:参数 src 和 dst 均为文件指针,其中:sr ...

  5. 嫌Excel VBA执行速度慢,这些建议你一定要看

    Excel是办公利器,这无需多言.尤其在办公室,Excel用的熟练与否,会的Excel知识点多不多,很大程度上决定了你工作是否高效,能否按时打卡下班.可我们也时常听到这样的吐槽:Excel好是好,可就 ...

  6. Ubuntu16桌面版编译和安装OpenCV4

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  7. 走进Task(1):什么是Task

    目录 前言 从表象讲起 Task 从何而来 Task 常见用法 Task 的分类 按是否包含 Result 分,也就是是否是泛型 Task 按得到 Task 的方式,可以分为 对 Task 进行分解 ...

  8. gin框架中的重定向

    重定向redirect func someRedirect(context *gin.Context) { context.Redirect(http.StatusMovedPermanently, ...

  9. 通过kubeadm工具部署k8s集群

    1.概述 kubeadm是一工具箱,通过kubeadm工具,可以快速的创建一个最小的.可用的,并且符合最佳实践的k8s集群. 本文档介绍如何通过kubeadm工具快速部署一个k8s集群. 2.主机规划 ...

  10. 学习JAVAWEB第十六天

    今天做了一个简单的登陆界面,HTML+CSS太不熟悉了,明天还得接着做