简介


Semaphore信号量计数器。和CountDownLatch,CyclicBarrier类似,是多线程协作的工具类,相对于join,wait,notify方法使用起来简单高效。下面我们主要看看它的用法吧!

实战


  • 限流。限制线程的并发数。

比如在一个系统中同时只能保证5个用户同时在线。

import java.util.concurrent.Semaphore;

/**
* @author :jiaolian
* @date :Created in 2021-03-04 11:13
* @description:Semaphore限流
* @modified By:
* 公众号:叫练
*/
public class LimitCurrnet {
public static void main(String[] args) throws InterruptedException {
//定义20个线程,每次最多只能执行5个线程;
Semaphore semaphore = new Semaphore(5);
for (int i=0; i<20; i++) {
new Thread(()->{
try {
//获取凭证
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"登录成功");
Thread.sleep(2000);
//释放凭证
semaphore.release();
System.out.println(Thread.currentThread().getName()+"用户退出");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}

如上代码所示:我们定义了20个用户同时访问系统,Semaphore参数是5,表示同时只能有5个用户可以获取凭证,其他用户必须等待直到有在线用户退出。调用semaphore.acquire()表示获取凭证,此时凭证数会减一,调用semaphore.release()表示释放凭证,凭证数会加一,如果系统中有等待的用户,操作此方法会通知等待的一个用户获取凭证成功,执行登录操作。最后打印部分结果如下:证明系统最多能保持5个用户同时在线。

注意:上面举出的这个案例,出个思考题:线程池是否可以实现呢?

  • 模拟CyclicBarrier,CountDownLatch重用!

Semaphore可以轻松实现CountDownLatch计数器,CyclicBarrier回环屏障,还记得CountDownLatch用法么?它是个计数器,可以帮我们统计线程执行时间,常用来测试多线程高并发执行接口效率,我们下面用Semaphore模拟多线程主线程等待子线程执行完毕再返回。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* @author :jiaolian
* @date :Created in 2021-03-01 21:04
* @description:信号量测试
* @modified By:
* 公众号:叫练
*/
public class SemaphoreTest { //定义线程数量;
private static final int THREAD_COUNT = 2;
//初始化信号量为0,默认是非公平锁
private static Semaphore semaphore = new Semaphore(0,false);
private static ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT); public static void main(String[] args) throws InterruptedException {
for (int i=0; i<THREAD_COUNT; i++) {
executorService.submit(()->{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行");
semaphore.release();
});
}
//获取2个信号量
semaphore.acquire(2);
System.out.println("主线程执行完毕");
executorService.shutdown();
}
}

如上代码所示:我们定义了Semaphore初始化信号量为0,默认是非公平锁,在主线程中用线程池提交2个线程,主线程调用semaphore.acquire(2)表示需要获取两个信号量,但此时初始化信号量为0,此时AQS中的state会是0-2=-2,state值小于0,所以主线程执行这句话会阻塞将其加入AQS同步队列,线程池两个线程等待2秒后会调用semaphore.release()释放2个信号量,此时AQS中的state会自增到0,会通知主线程退出等待继续往下执行。执行结果如下图所示。

有没有发现Semaphore用法可以模拟CountDownLatch,另外Semaphore通过调用acquire,release方法,还可以实现CyclicBarrier功能!我们不举例了。

实现原理


  • 相同点:本质上都是计数器,底层是依赖AQS操作state实现。
  • 异同点:CountDownLatch是共享锁实现,CyclicBarrier是独占锁实现,CountDownLatch通过调用countDown递减计数器只能使用一次,而CyclicBarrier通过调用await递减计数器可以达到“回环”重复的效果。Semaphore也是共享锁实现,通过调用release计数器是递增的,通过设置信号量可以实现CyclicBarrier,CountDownLatch功能。

总结


今天我们介绍了Semaphore,整理出来希望能对你有帮助,写的比不全,同时还有许多需要修正的地方,希望亲们加以指正和点评,喜欢的请点赞加关注哦。点关注,不迷路,我是【叫练公众号,微信号【jiaolian123abc】边叫边练。

Semaphore实战的更多相关文章

  1. 【Java并发编程实战】-----“J.U.C”:Semaphore

    信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个"共享锁". Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的ReentrantLock就是 ...

  2. Java并发编程原理与实战二十八:信号量Semaphore

    1.Semaphore简介 Semaphore,是JDK1.5的java.util.concurrent并发包中提供的一个并发工具类. 所谓Semaphore即 信号量 的意思. 这个叫法并不能很好地 ...

  3. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  4. 【Java并发编程实战】-----“J.U.C”:CountDownlatch

    上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...

  5. 【Java并发编程实战】-----“J.U.C”:CyclicBarrier

    在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...

  6. 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock

    ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...

  7. 【Java并发编程实战】-----“J.U.C”:锁,lock

    在java中有两种方法实现锁机制,一种是在前一篇博客中([java7并发编程实战]-----线程同步机制:synchronized)介绍的synchronized,而另一种是比synchronized ...

  8. java并发编程实战学习(3)--基础构建模块

    转自:java并发编程实战 5.3阻塞队列和生产者-消费者模式 BlockingQueue阻塞队列提供可阻塞的put和take方法,以及支持定时的offer和poll方法.如果队列已经满了,那么put ...

  9. Linux下的C编程实战

    Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来, Linu ...

随机推荐

  1. Educational Codeforces Round 94 (Rated for Div. 2) String Similarity、RPG Protagonist、Binary String Reconstruction、Zigzags 思维

    题目链接:String Similarity 题意: 首先题目定义了两个串的相似(串的构成是0.1),如果两个串存在对于一个下标k,它们的值一样,那么这两个串就相似 然后题目给你一个长度为2n-1的串 ...

  2. 2020 ICPC Asia Taipei-Hsinchu Regional Problem B Make Numbers (dfs搜索)

    题意:给你四个数字,你可以用这四个数字凑出四个1位数,一个2位数和两个1位数,或一个3位数和一个1位数,你可以用你凑出的数字进行\(+,-,x\)运算(所有运算符号至少出现一次),问你一共能得到多少个 ...

  3. poj2923 Relocation

    Description Emma and Eric are moving to their new house they bought after returning from their honey ...

  4. zoj3623 Battle Ships

    Battle Ships is a new game which is similar to Star Craft. In this game, the enemy builds a defense ...

  5. PowerShell随笔6---ISE

    简单的命令可以通过控制台窗口输入执行,但是我的脚本逻辑复杂,需要保存.总不能在命令行工具中执行吧. 关了窗口,啥都没了.有没有一个IDE,有. 在PowerShell命令行窗口中输入:ISE,就会打开 ...

  6. ElasticSearch 集群 & 数据备份 & 优化

    ElasticSearch 集群相关概念 ES 集群颜色状态 ①. - 红色:数据都不完整 ②. - 黄色:数据完整,但是副本有问题 ③. - 绿色:数据和副本全都没有问题 ES 集群节点类型 ①. ...

  7. 数据库之ODPS中sql语句指南

    此篇博文为本人在实际工作中应用总结,转载请注明出处. 持续更新中 一.增 1.增加一列(向csp_hsy_count_info表中增加sale_qty列) ALTER TABLE csp_hsy_co ...

  8. 2.安装Helm

    作者 微信:tangy8080 电子邮箱:914661180@qq.com 更新时间:2019-06-25 13:54:15 星期二 欢迎您订阅和分享我的订阅号,订阅号内会不定期分享一些我自己学习过程 ...

  9. codeforces 1037E-Trips 【构造】

    题目:戳这里 题意:n个点,每天早上会在这n个点中加一条边,每天晚上最大的子图满足子图中每个点都有k条或以上的边. 解题思路:看了官方题解,先把所有的点都连上,再从最后一天往前减边,用set维护最大的 ...

  10. Leetcode(145)-二叉树的后序遍历

    给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 思路:一开始编写二叉树后序遍历的程序,感觉定级为困难有点欠妥,确实,如果用 ...