JUC 常用 4 大并发工具类:CountDownLatch、CyclicBarrier、Semaphore、Exchanger
目录
CountDownLatch 倒计数锁存器
CyclicBarrier 循环栅栏锁
CycliBarriar VS CountdownLatch
Semaphore 计数信号量限制资源访问的线程数目
Exchanger 交换器
1、JUC 是指 java.util.concurrent 包,这个包俗称 JUC,里面都是解决并发问题的一些 API。
2、四大常用并发工具类: CountDownLatch、CyclicBarrier、Semaphore、ExChanger
CountDownLatch 倒计数锁存器
1、java.util.concurrent.CountDownLatch 是一个同步的辅助类,允许一个或多个线程,等待其他一组线程完成操作,再继续执行。可以理解为倒计数锁
2、再比如:主线程中开4个线程A、B、C、D去执行任务,分别是计算上一年1、2、3、4四个季度的某某数据,主线程一直等待到 A、B、C、D 执行完毕(数据计算完毕)后再进行数据汇总。
构造器
public CountDownLatch(int count) {if (count < 0) throw new IllegalArgumentException("count < 0");this.sync = new Sync(count);}
1、只有如上所示一个构造器,参数 count 表示闭锁需要等待的线程数量,这个值只能被设置一次,CountDownLatch 没有提供任何机制去重新设置这个计数值。
2、如果需要重置计数,请考虑使用 CyclicBarrier。
常用方法
await()
public void await() throws InterruptedException {sync.acquireSharedInterruptibly(1);}
1、使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。
2、如果当前计数为零,则此方法立即返回。
3、如果当前计数大于零,则出于线程调度目的,将禁用当前线程,且在发生以下两种情况之一前,该线程将一直处于休眠状态:
1)由于调用 countDown() 方法,计数到达零; 2)或者其他某个线程中断当前线程。 |
await(long timeout, TimeUnit unit)
1、使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。
2、如果当前计数为零,则此方法立刻返回 true 值。
3、如果当前计数大于零,则出于线程调度目的,将禁用当前线程,且在发生以下三种情况之一前,该线程将一直处于休眠状态:
1)由于调用 countDown() 方法,计数到达零; 2)或者其他某个线程中断当前线程; 3)或者已超出指定的等待时间。 |
countDown()
public void countDown() {sync.releaseShared(1);}
1、递减锁存器的计数,如果计数到达零,则释放所有等待的线程。 此方法是不会阻塞的!
2、如果当前计数大于零,则将计数减少。如果新的计数为零,出于线程调度目的,将重新启用所有的等待线程。
3、如果当前计数等于零,则不发生任何操作。
getCount()
public long getCount() {return sync.getCount();}
1、返回当前计数。 此方法通常用于调试和测试。
在线演示源码:src/test/java/org/example/se/concurrent/CountDownLatchTest.java · 汪少棠/java-se - Gitee.com
CyclicBarrier 循环栅栏锁
1、java.util.concurrent.CyclicBarrier 是一个同步辅助类,允许一组线程相互之间等待,达到一个共同点,再继续执行。可以理解为循环栅栏锁
2、相比与 CountDownLatch,CyclicBarrier 有一个 reset() 方法可以将将屏障重置为其初始状态,即恢复构造器中最开始设置的个数值
3、比如:8个运动员(线程)参加赛跑,必须得所有人都准备好了,才能开始比赛。再比如:游戏一方5个人(代表5个线程)组成团队赛,必须大家都准备好了,比赛才能开始
构造器
public CyclicBarrier(int parties) {this(parties, null);}
1、创建一个新的 CyclicBarrier,会让给定数量(parties)的参与者(线程)在调用await()方法(达到了栅栏)后处于等待状态,直到所有给定线程(parties)都调用了await方法(即都达到了栅栏)时,各自才恢复运行。
2、参数:parties - 在达到栅栏(barrier) 前必须调用 await() 的线程数
3、通俗的说:先到达栅栏(调用了await方法)的线程会被阻塞,直到同一组内的所有线程都达到栅栏时,大家才接着往后运行。
在线演示源码:src/test/java/org/example/se/concurrent/CyclicBarrierTest.java · 汪少棠/java-se - Gitee.com
CyclicBarrier(int parties, Runnable barrierAction)
public CyclicBarrier(int parties, Runnable barrierAction) {if (parties <= 0) throw new IllegalArgumentException();this.parties = parties;this.count = parties;this.barrierCommand = barrierAction;}
1、用于在所有线程到达屏障时,优先执行 barrierAction,方便处理更复杂的业务场景
2、通俗的说:先到达栅栏(调用了await方法)的线程会被阻塞,当同一组内的所有线程都达到栅栏时,会从中随机选一个线程去执行barrierAction任务,此任务执行完成后,所有线程再接着往后运行。
在线演示源码:src/test/java/org/example/se/concurrent/CyclicBarrierTest2.java · 汪少棠/java-se - Gitee.com
常用方法
public int await() throws InterruptedException, BrokenBarrierException {try {return dowait(false, 0L);} catch (TimeoutException toe) {throw new Error(toe); // cannot happen;}}
1、调用该方法会使当前线程在栅栏点发生阻塞,直到循环栅栏指定的线程数量都达到栅栏点时恢复执行
2、返回:到达的当前线程的索引,其中,索引 getParties() - 1 指示将到达的第一个线程,零表示最后一个到达的线程
3、如果当前线程不是到达栅栏的最后一个线程,出于调度目的,将禁用它,且在发生以下任意情况之前,该线程将一直处于休眠状态:
1)最后一个线程到达;或者 2)其他某个线程中断当前线程;或者 3)其他某个线程中断另一个等待线程;或者 4)其他某个线程在等待 barrier 时超时;或者 5)其他某个线程在此 barrier 上调用 reset()。 |
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException {return dowait(true, unit.toNanos(timeout));}
1、类似于await(),只是增加了线程等待时的超时时间 2、如果超出指定的等待时间,则抛出 TimeoutException 异常。如果该时间小于等于零,则此方法根本不会等待。 |
public int getNumberWaiting() {final ReentrantLock lock = this.lock;lock.lock();try {return parties - count;} finally {lock.unlock();}}
1、返回当前在栅栏处等待的参与者数目,此方法主要用于调试和断言。
public int getParties() {return parties;}
1、返回要求启动此 barrier 的参与者数目。
2、通俗的将是:获得构造函数中指定的需要在栅栏点阻塞的线程数量
public void reset() {final ReentrantLock lock = this.lock;lock.lock();try {breakBarrier(); // break the current generationnextGeneration(); // start a new generation} finally {lock.unlock();}}
CycliBarriar VS CountdownLatch
1、CyclicBarrier 可以重复使用(reset方法可置0),而 CountdownLatch 不能重复使用。
2、Java 的 concurrent 包里面的 CountDownLatch 其实可以把它看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器,也就是同时只能有一个线程去减这个计数器里面的值。
3、可以向 CountDownLatch 对象设置一个初始的数字作为计数值,任何调用这个对象上的await()方法都会阻塞,直到这个计数器的计数值被其他的线程减为0为止。
4、所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。
5、CyclicBarrier 是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
Semaphore 计数信号量限制资源访问的线程数目
public class java.util.concurrent.Semaphore implements java.io.Serializable {
1、JDK1.5 提供的 Semaphone 计数信号量维护了一个许可证集,线程中调用 acquire() 方法从 Semaphone 中获取许可证,得到了许可证,Semaphone 的许可证数减1,线程继续向后运行,未得到许可证时,线程一直阻塞在 acquire()。
2、线程中获得许可执行完毕后,使用 release() 方法归还许可证到 Semaphone,Semaphone 的许可证数加1,此时其余阻塞在 acquire() 的线程便可以获取其它线程归还的许可证后继续执行。
3、Semaphore 只对可用许可的号码进行计数,并采取相应的行动,信号量常常用于多线程的代码中,限制访问某些资源(物理或逻辑的)的线程数目,比如数据库连接池。
4、因为 Semaphone 的许可证数量是固定的,所以同一时刻最多只能有 Semaphone 许可证同等数量的线程访问,其余线程访问时必须等待已经拿到许可证的线程执行完毕(执行完毕的线程要归还许可证)。
常用方法
构造方法摘要 | ||
---|---|---|
|
创建具有给定的许可数和非公平的公平设置的 Semaphore 。
|
|
|
创建具有给定的许可数和给定的公平设置的 Semaphore 。
|
方法摘要 | |
---|---|
|
从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。 获取一个许可(如果提供了一个)并立即返回,将可用的许可数减 1。 |
|
从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。 |
|
返回此信号量中当前可用的许可数。 |
|
获取并返回立即可用的所有许可。 |
|
释放一个许可,将其返回给信号量。 |
|
释放给定数目的许可,将其返回到信号量。 |
|
返回标识此信号量的字符串,以及信号量的状态。 |
|
如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。 |
在线演示源码:src/test/java/org/example/se/concurrent/SemaphoreTest.java · 汪少棠/java-se - Gitee.com
Exchanger 交换器
1、Exchanger,俗称交换器,用于在线程之间交换数据,但是比较受限,因为只能两个线程之间交换数据
在线演示源码:src/test/java/org/example/se/concurrent/ExchangeTest.java · 汪少棠/java-se - Gitee.com
JUC 常用 4 大并发工具类:CountDownLatch、CyclicBarrier、Semaphore、Exchanger相关推荐
- JUC 常用 4 大并发工具类
欢迎关注方志朋的博客,回复"666"获面试宝典 什么是JUC? JUC就是java.util.concurrent包,这个包俗称JUC,里面都是解决并发问题的一些东西 该包的位置位 ...
- Java多线程系列(九):CountDownLatch、Semaphore等4大并发工具类详解
之前谈过高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 ,以及高并发编程系列:ConcurrentHashMap的实现原理(JDK1.7和JDK1.8) 今天主要介绍concurre ...
- Java并发工具类(三)Exchanger
Java并发工具类(三)Exchanger 在J.U.C并发包中提供了一些工具类,可以供我们在日常的开发中,根据不同的情况去进行一些相关的并发控制,具体的类有: CountDownLatch Sema ...
- 高并发编程系列:4大并发工具类的功能、原理、以及应用场景
通常我们所说的并发包也就是java.util.concurrent,集中了Java并发工具类和并发容器等,今天主要介绍Java并发编程的工具类,我先从Java并发工具包谈起. 01 - 并发工具包涵盖 ...
- JAVA并发:并发工具类CountDownLatch、CyclicBarrier、Semaphore使用及源码分析
在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 1 CountDownLa ...
- 多线程-并发工具类之CyclicBarrier详解
文章目录 简介 例子 实现原理 小结 简介 从字面意思理解,CyclicBarrier是回环屏障的意思,它可以让一组线程全部达到一个状态后再全部同时执行.这里之所以叫作回环是因为当所有等待线程执行完毕 ...
- 死磕Java并发:J.U.C之并发工具类:CyclicBarrier
作者:chenssy 来源:Java技术栈公众号 CyclicBarrier,一个同步辅助类,在API中是这么介绍的: 它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier ...
- Java并发工具类(闭锁CountDownLatch)
并发工具类系列: Java并发工具类(闭锁CountDownLatch) Java并发工具类(栅栏CyclicBarrier) Java并发工具类(信号量Semaphore) 闭锁是一种同步工具类,可 ...
- 15.并发工具类(解析hashtable,ConcurrentHashMap1.7与1.8的区别以及Semaphore)
3. 并发工具类 3.1 并发工具类-Hashtable Hashtable出现的原因:在集合类中HashMap是比较常用的集合对象,但是HashMap在多线程环境下可能会出现线程不安全的情况,为了保 ...
- 死磕Java并发:J.U.C之并发工具类:Exchanger
作者:chenssy 来源:Java技术驿站 前面三篇博客分别介绍了CyclicBarrier.CountDownLatch.Semaphore,现在介绍并发工具类中的最后一个Exchange.Exc ...
最新文章
- 超详细的Python matplotlib 绘制柱状图
- echarts仪表盘option_echarts仪表盘完整代码
- 2017-12-04HTML布局_div布局
- 24岁博士毕业,受聘211高校副教授,90后开挂背后是自律和坚持
- java学习(14):java命名规范
- 关于无法加载已创建的布局文件的问题的解决方案以及已布局在对应的R文件中未生成相应ID的问题的解决
- lisp java_从Java调用的LISP代码
- 星星怎么分布_阿玛尼满天星手表怎么辨真假
- 【项目管理】------九大项目管理框架 (
- 【版本控制工具】svn服务器、客户端安装配置及eclipse的svn检出
- Directx11教程(54) 简单的基于GS的billboard实现
- 为什么不要在android log中打印中文_Android 开发:揭开App秒开的奥秘
- 弹性板计算和板带划分计算_彻底搞懂板带的配筋及范围
- 深入理解Java虚拟机——Java堆栈跟踪工具(jstack)
- 浅谈JPA一:JPA是什么?
- oracle block corrupted,ORA-01578: ORACLE data block corrupted (file # 6, block # 132)
- table 手机 滑动_移动端touch事件滚动
- Python语言入门这一篇就够了-学习笔记(十二万字)
- 信息学奥赛一本通 1335:【例2-4】连通块
- 详解“==”和equals的区别
热门文章
- 漫谈 Clustering (番外篇): Vector Quantization
- MaxEnt: 最大熵模型(Maximum Entropy Models)(一)
- Harris角点检测算法 1
- 如果P = NP 则 NP = co-NP.
- 拓端tecdat|R语言广义线性模型GLM:线性最小二乘、对数变换、泊松、二项式逻辑回归分析冰淇淋销售时间序列数据和模拟
- 拓端tecdat:R语言STAN贝叶斯线性回归模型分析气候变化影响北半球海冰范围和可视化检查模型收敛性
- 拓端tecdat|R语言用泊松Poisson回归、GAM样条曲线模型预测骑自行车者的数量
- python实现卷积操作
- 软件工程 第六章 编码与测试
- mysql centos_centos7mysql安装