JAVA并发编程之倒计数器CountDownLatch
CountDownLatch 的使用场景:在主线程中开启多线程去并行执行任务,并且主线程需要等待所有子线程执行完毕后汇总返回结果。
我把源码中的英文注释全部删除,写上自己的注释。就剩下 70 行不到的代码,很简单了。
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer; public class CountDownLatch {
// 自定义一个属性,继承 抽象队列同步器
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L; Sync(int count) {
setState(count);
} int getCount() {
return getState();
} @Override
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
} @Override
protected boolean tryReleaseShared(int releases) {
for (;;) {
int c = getState();
if (c == 0) {
return false;
}
int nextc = c-1;
if (compareAndSetState(c, nextc)) {
return nextc == 0;
}
}
}
}
//定义私有属性,该类继承 抽象队列同步器
private final java.util.concurrent.CountDownLatch.Sync sync; // 构造方法,传入数字,用于倒计数
public CountDownLatch(int count) {
if (count < 0) {
throw new IllegalArgumentException("count < 0");
}
this.sync = new java.util.concurrent.CountDownLatch.Sync(count);
}
// 阻塞当前线程,直到count=0才唤醒线程
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
// 阻塞当前线程,直到count=0才唤醒线程。
// 设置定时时间到了,也会唤醒线程。
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
//count 减 1
public void countDown() {
sync.releaseShared(1);
}
//获取 count
public long getCount() {
return sync.getCount();
}
//toString方法,获取字符串
public String toString() {
return super.toString() + "[Count = " + sync.getCount() + "]";
}
}
我用这个CountDownLatch来实现多线程执行任务,合并结果返回。
//创建线程池
ExecutorService pool = Executors.newCachedThreadPool();
//定义集合存储结果
List<Object> values = new ArrayList<>();
//定义倒计数器
CountDownLatch count = new CountDownLatch(2); //线程池执行任务1
pool.submit(new Runnable() {
@Override
public void run() {
try {
//线程池进行计算1,得到结果1。
String value1 = "结果1";
//把结果加入共享变量中。
values.add(value1);
} catch (Exception e) {
e.printStackTrace();
}finally {
//finally 中保证一定会执行 减1
//计数器减 1
count.countDown();
} }
}); //线程池执行任务2
pool.submit(new Runnable() {
@Override
public void run() {
try {
//线程池进行计算2,得到结果2。
String value2 = "结果2";
//把结果加入共享变量中。
values.add(value2);
} catch (Exception e) {
e.printStackTrace();
}finally {
//finally 中保证一定会执行 减1
//计数器减 1
count.countDown();
} }
});
//线程阻塞等待
count.await(); //返回多线程执行的结果。
return values;
多线程并发编程,就是这么简单!不用Callable,也能获取到线程池的返回值哦。
JAVA并发编程之倒计数器CountDownLatch的更多相关文章
- Java并发编程-JUC-CountDownLatch 倒计数门闩器-等待多线程完成再放行 -一次性使用
如题 (总结要点) CountDownLatch 倒计数门闩器, 让1-n-1个线程等待其他多线程完成工作. (Excel的多个Sheet的解析,最终等待解析完毕后;要实现主线程等待所有线程完成she ...
- 并发编程-concurrent指南-计数器CountDownLatch
java.util.concurrent.CountDownLatch 是一个并发构造,它允许一个或多个线程等待一系列指定操作的完成. CountDownLatch 以一个给定的数量初始化.count ...
- Java并发编程:Semaphore、CountDownLatch、CyclicBarrier
首先我们来实现一个功能:当我们启动一个系统的时候需要初始化许多数据,这时候我们可能需要启动很多线程来进行数据的初始化,只有这些系统初始化结束之后才能够启动系统.其实在Java的类库中已经提供了Sema ...
- Java并发编程_wait/notify和CountDownLatch的比较(三)
1.wait/notify方法 package sync; import java.util.ArrayList; import java.util.List; public class WaitA ...
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...
- Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
- Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Phaser)
我在<JDK1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...
- Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semphore、Phaser)
我在<jdk1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...
- 14、Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...
随机推荐
- java里字节与字符的区别
当时学Java的时候没搞懂字节和字符的区别,今天看文件输入输出流的时候觉得是时候彻底把这两个概念弄懂. 首先得知道byte的概念和作用: byte即字节的意思,是java中的基本数据类型,用来申明字节 ...
- spring源码深度解析— IOC 之 bean 的初始化
一个 bean 经历了 createBeanInstance() 被创建出来,然后又经过一番属性注入,依赖处理,历经千辛万苦,千锤百炼,终于有点儿 bean 实例的样子,能堪大任了,只需要经历最后一步 ...
- redux和react-redux做简单组件控制
这次我们用两种方式实现以下要求 1.三个组件 2.第一个组件有两个按钮 分别控制第二和第三个组件年龄和姓名的改变 3第二个组件展示姓名,第三个组件展示年龄 用到哪些插件 store redux 一 ...
- mysql 安装使用
本节掌握内容: MySQL的介绍安装.启动 windows上制作服务 MySQL破解密码 MySQL中统一字符编码 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 O ...
- spring的context:exclude-filter 与 context:include-filter
1 在主容器中(applicationContext.xml),将Controller的注解打消掉 <context:component-scan base-package="com& ...
- PCB 板边倒圆角的实现方法(基本算法一)
PCB外形是直角时外形时,通常工程制作时,外是直角或尖角的地方倒圆角,主要是为了防止板边容易划伤板且容易扎伤人 所以当客户没有特殊要求时,PCB外形是直角时一般会默认倒角0.5mm圆角(如下图所示) ...
- python接口自动化(二十九)--html测试报告通过邮件发出去——上(详解)
简介 前边几篇,已经教小伙伴们掌握了如何生成HTML的测试报告,那么生成测试报告,我们也不能放在那里不管了,这样即使你报告在漂亮,领导也看不到.因此如果想向领导汇报工作,不仅需要提供更直观的测试报告. ...
- 【弱化版】【P3371 【模板】单源最短路径(弱化版)】-C++
→原题传送门← 看到题目描述我就知道,这道题不能用SPFA[手动补滑稽] 那么我这道题目采用的是dijkstra算法不了解的去补一下知识哈. dij的模板: #include<bits/stdc ...
- [USACO09OCT]Invasion of the Milkweed】乳草的侵占-C++
Farmer John一直努力让他的草地充满鲜美多汁的而又健康的牧草.可惜天不从人愿,他在植物大战人类中败下阵来.邪恶的乳草已经在他的农场的西北部份占领了一片立足之地. 草地像往常一样,被分割成一个高 ...
- 图像识别sift+bow+svm
本文概述 利用SIFT特征进行简单的花朵识别 SIFT算法的特点有: SIFT特征是图像的局部特征,其对旋转.尺度缩放.亮度变化保持不变性,对视角变化.仿射变换.噪声也保持一定程度的稳定性: SIFT ...