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,也能获取到线程池的返回值哦。
原文:https://www.cnblogs.com/itbac/p/11296534.html