JUC包下的CountDownLatch,CyclicBarrier,Semaphore
时间:2022-04-29
本文章向大家介绍JUC包下的CountDownLatch,CyclicBarrier,Semaphore,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
①.从CountDownLatch的设计来看,可以做汇总的操作,例如计算员工工资,这边启动多个线程同时计算等所有线程执行完毕之后,计算需要发放的总额
final ConcurrentHashMap<String, Integer> resultMap = new ConcurrentHashMap<String, Integer>();
final CountDownLatch c = new CountDownLatch(10);
final Random r = new Random();
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
String sub =Thread.currentThread().getName().substring(Thread.currentThread().getName().indexOf("-")+1);
System.out.println("threadName:" + Thread.currentThread().getName());
if(Integer.parseInt(sub) %2 == 0){
System.out.println(Thread.currentThread().getName()+" wait 2s");
Thread.sleep(2000);
}else{
System.out.println(Thread.currentThread().getName()+" wait 0.5s");
Thread.sleep(500);
}
resultMap.put(Thread.currentThread().getName(), r.nextInt(10000));
c.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
c.await();
System.out.println("n***********************n");
int sum = 0;
for(String key :resultMap.keySet()){
Integer num = resultMap.get(key);
sum += num;
System.out.println(num);
}
System.out.println("end:"+sum);
控制台:
threadName:Thread-2
threadName:Thread-4
Thread-2 wait 2s
threadName:Thread-3
Thread-3 wait 0.5s
threadName:Thread-6
Thread-6 wait 2s
threadName:Thread-1
Thread-1 wait 0.5s
threadName:Thread-0
Thread-0 wait 2s
Thread-4 wait 2s
threadName:Thread-8
Thread-8 wait 2s
threadName:Thread-7
Thread-7 wait 0.5s
threadName:Thread-5
Thread-5 wait 0.5s
threadName:Thread-9
Thread-9 wait 0.5s
***********************
8881
7993
3441
8408
100
1074
6542
4448
4216
2839
end:47942
②.CyclicBarrier可以用来做初始化操作之后,所有的线程统一执行:
System.out.println("init finish.");
System.out.println("************************");
final CyclicBarrier cb = new CyclicBarrier(10);
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("ThreadName:" + Thread.currentThread().getName());
Thread.sleep(3000);
cb.await();
System.out.println("ThreadName:" + Thread.currentThread().getName()
+ ",end!");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}).start();
}
控制台:
init finish.
************************
ThreadName:Thread-0
ThreadName:Thread-1
ThreadName:Thread-2
ThreadName:Thread-3
ThreadName:Thread-4
ThreadName:Thread-5
ThreadName:Thread-6
ThreadName:Thread-7
ThreadName:Thread-8
ThreadName:Thread-9
ThreadName:Thread-7,end!
ThreadName:Thread-1,end!
ThreadName:Thread-2,end!
ThreadName:Thread-8,end!
ThreadName:Thread-9,end!
ThreadName:Thread-4,end!
ThreadName:Thread-3,end!
ThreadName:Thread-0,end!
ThreadName:Thread-6,end!
ThreadName:Thread-5,end!
③.Semaphore(信号量)
//构造方法permits表示一次性接受几个线程通过,比如有20个线程,permits=5,那么则表示一次性可以有五个线程通过,若为1那么作用相当于是一把锁,
new Semaphore(permits);
acquire相当于是用来获取一个令牌,每获取一个令牌则减少一个,当所有令牌用完之后,剩余线程进入等待,直到有其他线程执行完毕并且归还令牌,剩余线程准备抢夺令牌以便执行,
ExecutorService exec = Executors.newCachedThreadPool();
// 只能5个线程同时访问
final Semaphore semp = new Semaphore(5);
for (int i = 0; i < 20; i++) {
final int NO = i;
Runnable run = new Runnable() {
public void run() {
try {
// 获取许可
semp.acquire();
System.out.println("No: " + (NO+1));
Thread.sleep(2000);
// 访问完后,释放
semp.release();
System.out.println("------------");
System.out.println("availability:" + semp.availablePermits());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
exec.execute(run);
}
// 退出线程池
exec.shutdown();
从控制台可以看出,第一次5个线程一起执行,后面线程的执行受上一次线程执行并且释放令牌时间的影响 ,等所有线程执行完毕则显示共有五个令牌可以使用
No: 1
No: 2
No: 4
No: 3
No: 5
------------
No: 8
No: 6
------------
availability:0
------------
availability:0
------------
------------
availability:0
availability:0
availability:0
No: 10
No: 7
No: 9
No: 12
------------
availability:0
------------
No: 11
No: 13
------------
------------
availability:0
------------
availability:0
No: 15
availability:0
No: 14
availability:1
------------
No: 16
availability:0
------------
No: 18
No: 17
------------
availability:0
------------
availability:0
availability:0
No: 19
------------
No: 20
availability:0
------------
availability:1
------------
------------
availability:3
availability:3
------------
availability:4
------------
availability:5
- [原创]Fluent NHibernate之旅(四)-- 关系(中)
- 华为专家 | 轻量化微服务测试实践
- Android Material Design系列之Navigation Drawer
- [原创]Fluent NHibernate之旅(四)-- 关系(下)
- 一次通过漏洞挖掘成功渗透某网站的过程
- 使用fuzzDB进行web安全测试
- Android Material Design系列之FloatingActionButton和Snackbar
- Fluent Nhibernate之旅(五)--利用AutoMapping进行简单开发
- Android Material Design系列之Toolbar
- Struts2 S2-020在Tomcat 8下的命令执行分析
- Struts2再曝S2-020补丁绕过漏洞 – 万恶的正则表达式
- 学习BlogEngine.Net解读笔记系列(一)
- Android面试系列之应用内多语言切换
- Android面试系列之AsyncTask
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- VIM个性化配置(一)
- Django+Vue开发生鲜电商平台之6.使用Vue实现商品类别和商品数据前台显示
- 【程序源代码】基于Python开发的Markdown在线文档系统
- 深度学习Pytorch检测实战 - Notes - 第4章 两阶经典检测器:Faster RCNN
- Numpy中的两个乱序函数
- PerfDog4.0探索,支持用户自建web云
- 跨帐号访问COS资源
- 聊聊dubbo-go的DubboProtocol
- 推荐一个很牛叉的开源Flask项目
- 机器学习应用资产管理系列一:强化学习策略(附代码)
- 3分钟短文 | Laravel模型关联删除表记录,用观察者还是事件钩子
- 原理+代码|深入浅出Python随机森林预测实战
- 3分钟短文 | Laravel复杂SQL超多WHERE子句,本地作用域你没用过
- 3分钟短文 | Laravel同时连接多个数据库,你用啥办法?
- 3分钟短文 | PHP 连接2个字符串的8个方法,新手常犯错