当前位置:网站首页>线程间控制之CountDownLatch和CyclicBarrier使用介绍
线程间控制之CountDownLatch和CyclicBarrier使用介绍
2022-04-23 14:07:00 【pureluckyfish】
一、CountDownLatch介绍
CountDownLatch类(采用减法计数);是一个线程同步辅助工具类和CyclicBarrier类(采用加法计数)功能类似,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。
二、CountDownLatch俩种应用场景:
场景一:所有线程在等待开始信号startSignal.await(),主流程发出开始信号通知,既执行startSignal.countDown()方法后,所有线程才开始执行;每个线程执行完发出做完信号,既执行doneSignal.countDown()方法;当所有线程都执行完毕后,主流程才能继续往下执行。
package ThreadStudy;
import java.util.concurrent.CountDownLatch;
public class Driver1 {
public static void main(String[] args) throws InterruptedException {
int N = 5;
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; i++) {
new Thread(new Work1(startSignal, doneSignal)).start();
}
//此时所有线程处于等待状态
System.out.println("doSomethingElse()");
//让所有线程执行
startSignal.countDown();
//等待所有线程执行完毕
doneSignal.await();
System.out.println("doSomethingElse()");
}
}
class Work1 implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
public Work1(CountDownLatch startSignal,CountDownLatch doneSignal) {
this.startSignal=startSignal;
this.doneSignal= doneSignal;
}
@Override
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
void doWork() {
System.out.println("doWork()");
}
}
场景二:把一个大问题分成N个部分,每一个部分对应一个线程放到线程池中执行,当每一个线程执行完成完毕后发出做完信号,既调用doneSignal.countDown()方法;当所有线程都执行完毕后,主流程才能继续往下执行。
package ThreadStudy;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Driver2 {
public static void main(String[] args) throws Exception {
int N = 5;
CountDownLatch doneSignal = new CountDownLatch(N);
//定义线程池
ExecutorService exec = Executors.newSingleThreadExecutor();
for (int i = 0; i < N; i++) {
exec.execute(new Work2(doneSignal, i));
}
//等待所有线程执行完成
doneSignal.await();
System.out.println("doSomethingElse()");
//关闭线程池
exec.shutdown();
}
}
class Work2 implements Runnable {
private CountDownLatch doneSignal;
private int i;
public Work2(CountDownLatch doneSignal, int i) {
this.doneSignal = doneSignal;
this.i = i;
}
@Override
public void run() {
doWork(i);
doneSignal.countDown();
}
void doWork(int i) {
System.out.println("doWork():" + i);
}
}
三、CountDownLatch与CyclicBarrier对比
CountDownLatch | CyclicBarrier | |
相同点 | 都是同步辅助工具类 | |
不同点 | 减法计数,一次性使用 | 加法计数,可循环使用 |
构造方法 | CountDownLatch(int count) |
CyclicBarrier(int parties) |
CyclicBarrier(int parties, Runnable barrierAction) | ||
普通方法 | await() | await() |
await(long timeout, TimeUnit unit) | await(long timeout, TimeUnit unit) | |
countDown() | getNumberWaiting() | |
getCount() | getParties() | |
toString() | isBroken() | |
reset() |
四、CountDownLatch类中方法使用示例
package ThreadStudy;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class Csdn {
public static void main(String[] args) throws Exception {
int countLatch = 3;
// 创建指定个数的门闩
CountDownLatch countDownLatch = new CountDownLatch(countLatch);
System.out.println("toString方法0:" + countDownLatch.toString());
for (int i = 0; i < countLatch; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
// 门闩数减一
Thread.sleep(3000);
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
// 获取门闩数量
long n = countDownLatch.getCount();
System.out.println("门闩数量:" + n);
// 指定等待的超时时间
countDownLatch.await(1, TimeUnit.SECONDS);
System.out.println("过了超时时间程序继续往下执行");
// 当前线程等待,直到门闩数是0,程序才往下执行
countDownLatch.await();
System.out.println("toString方法1:" + countDownLatch.toString());
}
}
五、CyclicBarrier类中方法使用示例
package ThreadStudy;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
public class CyclicBarrierTest {
public static void main(String[] args) {
// 构造方法一:创建一个线程为3的循环障碍点,3个线程都到达障碍点后,才往下走!
CyclicBarrier cb1 = new CyclicBarrier(3);
// 构造方法二:创建一个新的CyclicBarrier,当最后一个线程通过障碍点后会触发此处的线程执行
CyclicBarrier cb = new CyclicBarrier(3, new Runnable() {
@Override
public void run() {
System.out.println("==通过障碍点后触发执行的线程==");
}
});
// 返回当前在屏障处等待的人数。此方法主要用于调试和断言
int a = cb.getNumberWaiting();
System.out.println("返回当前在屏障处等待的人数" + a);
// 返回跨越该障碍所需的人数
int b = cb.getParties();
System.out.println("返回跨越该障碍所需的人数:" + b);
// 查询此屏障是否处于中断状态:
boolean bo = cb.isBroken();
System.out.println("查询此屏障是否处于中断状态:" + bo);
for (int i = 0; i < 4; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程:" + Thread.currentThread().getName() + "进入障碍点等待");
try {
// 等待,直到所有各方都调用了这个屏障上的await。
int d = cb.await();
System.out.println("d:" + d);
// 等待,直到所有各方都调用了此屏障上的await,或指定的等待时间过去
int c = cb.await(1, TimeUnit.SECONDS);
System.out.println("c:" + c);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("通过障碍点");
}
}).start();
}
// 复位操作,此时在障碍点等待的线程会抛出BrokenBarrierException异常
cb.reset();
}
}
版权声明
本文为[pureluckyfish]所创,转载请带上原文链接,感谢
https://blog.csdn.net/sinat_33918956/article/details/122469143
边栏推荐
- 帆软中需要设置合计值为0时,一整行都不显示的解决办法
- 使用开源调研工具Prophet是一种什么体验?
- OpenStack如何跨版本升级
- log4j 输出日志信息到文件中
- org.apache.parquet.schema.InvalidSchemaException: A group type can not be empty. Parquet does not su
- Subscription number development of wechat applet (message push)
- 不同时间类型的执行计划计算
- 云迁移的六大场景
- Prediction of tomorrow's trading limit of Low Frequency Quantization
- 基于微信小程序的wifi模块使用
猜你喜欢
星界边境Starbound创意工坊订阅的mod的存放路径
Gartner预测云迁移规模大幅增长;云迁移的优势是什么?
MYSQL 主从同步避坑版教程
帆软中需要设置合计值为0时,一整行都不显示的解决办法
关于NodeJS中JSON5的相关配置和使用
云迁移的六大场景
Detailed tutorial on the use of setinterval timing function of wechat applet
查询2013年到2021年的数据,只查询到2020的数据,遇到了这个问题所进行的解决办法
RecyclerView高级使用(一)-侧滑删除的简单实现
Chapter I review of e-commerce spike products
随机推荐
mysql 5.1升级到5.68
poi操作word模板替换数据并且导出word
Understand the concepts of virtual base class, virtual function and pure virtual function (turn)
Wechat applet input hidden and inoperable settings
JDBC和servlet写CRUD的接口总结
帆软实现分页时第一行和最后两行冻结方式
leetcode--357. Count the number of different figures
关于云容灾,你需要知道这些
VMWare安装64位XP中文教程
微信小程序的订阅号开发(消息推送)
使用itextpdf实现截取pdf文档第几页到第几页,进行分片
win10自带Groove音乐不能播放CUE和APE文件的一种曲线救国办法,自己创建aimppack插件包,AIMP安装DSP插件
switch使用(微信小程序)
Win10 comes with groove music, which can't play cue and ape files. It's a curvilinear way to save the country. It creates its own aimpack plug-in package, and aimp installs DSP plug-in
Wechat applet positioning and ranging through low-power Bluetooth device (2)
Cdh6 based on CM management 3.2 cluster integration atlas 2 one
Promtail + Loki + Grafana 日志监控系统搭建
帆软中使用if else 进行判断-使用标题条件进行判断
服务器日志分析工具(识别,提取,合并,统计异常信息)
jsp学习3