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的更多相关文章

  1. Java并发编程-JUC-CountDownLatch 倒计数门闩器-等待多线程完成再放行 -一次性使用

    如题 (总结要点) CountDownLatch 倒计数门闩器, 让1-n-1个线程等待其他多线程完成工作. (Excel的多个Sheet的解析,最终等待解析完毕后;要实现主线程等待所有线程完成she ...

  2. 并发编程-concurrent指南-计数器CountDownLatch

    java.util.concurrent.CountDownLatch 是一个并发构造,它允许一个或多个线程等待一系列指定操作的完成. CountDownLatch 以一个给定的数量初始化.count ...

  3. Java并发编程:Semaphore、CountDownLatch、CyclicBarrier

    首先我们来实现一个功能:当我们启动一个系统的时候需要初始化许多数据,这时候我们可能需要启动很多线程来进行数据的初始化,只有这些系统初始化结束之后才能够启动系统.其实在Java的类库中已经提供了Sema ...

  4. Java并发编程_wait/notify和CountDownLatch的比较(三)

     1.wait/notify方法 package sync; import java.util.ArrayList; import java.util.List; public class WaitA ...

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

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

  6. Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

    Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...

  7. Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Phaser)

    我在<JDK1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...

  8. Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semphore、Phaser)

    我在<jdk1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...

  9. 14、Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

    Java并发编程:CountDownLatch.CyclicBarrier和Semaphore 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch ...

随机推荐

  1. Spring 之Aop实现日志记录

    Aop实现见代码,简单demo实现 package com.idcos.automate.config; import com.idcos.automate.dal.auto.dao.dcos.Dco ...

  2. Java基础篇01

    01. 面向对象 --> 什么是面向对象 面向对象 面向对象程序设计,简称OOP(Object Oriented Programming). 对象: 指人们要研究的任何事物,不管是物理上具体的事 ...

  3. 了解selenium--(虫师的博客)

    Selenium is a portable software-testing framework for web applications. Selenium is composed of seve ...

  4. Linux上安装Nginx依赖环境和库、Nginx安装,Nginx服务命令

    安装Nginx依赖环境和库.Nginx安装,Nginx服务命令 因为Nginx官方提供的是C源码,要自己进行编译,所以需要自己拥有编译所依赖的环境和库才可正常编译 安装gcc yum -y insta ...

  5. 使用Appium做手机自动化录制问题

    最近在使用appium做Android手机自动化脚本录制, 发现点击“tap”时,一直没有用,页面还是不能跳转. 咋办?发愁... 于是看到旁边有个“sendkeys”,那是不是能够直接发送参数不就行 ...

  6. MagicBook屏幕频闪解决方案(Windows、MacOS)

    对于已经看到这篇文章的小伙伴们,就不解释何为PWM调光频闪了. MagicBook笔记本性价比高,但屏幕素质确实很一般,我们人眼看不出来的频闪,实际对眼睛损害很大,如图(需要设置快门参数,如1/400 ...

  7. python - 博客目录

    博客目录 python基础部分 函数 初识函数 函数进阶 装饰器函数 迭代器和生成器 内置函数和匿名函数 递归函数 常用模块 常用模块 模块和包 面向对象 初识面向对象 面向对象进阶 网络编程 网络编 ...

  8. python初识(3)

    bool 字符串 for循环 bool 数字非零全都是True 字符串非空全都是True 字符串 索引 从0开始 0 切片选取 [x:y] 左闭右开区间 [x:y:z] 选取x到y之间 每隔z选取一次 ...

  9. 记2017青岛ICPC

    2017青岛ICPC 11月4日 早上很早到达了青岛,然后去报道,走了好久的校园,穿的很少冷得瑟瑟发抖.中午教练请吃大餐,吃完饭就去热身赛了. 开幕式的时候,教练作为教练代表讲话,感觉周围的队伍看过来 ...

  10. Django用户头像上传

    1 将文件保存到服务器本地 upload.html ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!DOCTYPE html> <html ...