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,也能获取到线程池的返回值哦。

最新文章

  1. wap支付宝接口的问题
  2. Linux打包与压缩及tar命令详解
  3. SqlServer触发器判断对表操作类型(增、删、改)并将修改后的数据映射到新表
  4. 使用SQL语句 检测 MSSQL死锁
  5. Physical Based Shading in Unreal Engine 3
  6. python函数式编程
  7. 状压DP SGU 223 Little Kings
  8. *MySQL卸载之后无法重装,卡在Apply security settings:Error Nr.1045
  9. Codeforces 596D Wilbur and Trees
  10. 监控mysql执行的sql语句
  11. Netty4.0学习教程
  12. java 参数传值
  13. 解决:org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression &#39;requestMap.maintenancename != null and requestMap.maintenance
  14. windows粘贴板操作-自己的应用和windows右键互动
  15. docker部署archery
  16. 小程序canvas绘制渐变色(简单入门)
  17. 【转载】浅谈38K红外发射接受编码
  18. RBAC 继完善代码之后的,再一次完善
  19. Solr 配置中文分词器 IK
  20. Android.mk(3) 宏

热门文章

  1. MySQL字符集乱码详解
  2. 使用release自动打包发布正式版详细教程
  3. Android 上传开源项目到 jcenter 实战踩坑之路
  4. hive 常用的 join 操作 实例
  5. js常用设计模式实现(一)单例模式
  6. springcloud-路由gateway
  7. 【POJ - 1573】Robot Motion
  8. Java编程思想:利用内部类实现的工厂模式
  9. I/O:Writer
  10. UEditor 之初体验后记