本文共 2921 字,大约阅读时间需要 9 分钟。
如何让一段程序并发的执行,并最终汇总结果?
使用CyclicBarrier 在多个关口处将多个线程执行结果汇总, CountDownLatch 在各线程执行完毕后向总线程汇报结果。
CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。
CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待,而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。
从api上理解就是CountdownLatch有主要配合使用两个方法countDown()和await(),countDown()是做事的线程用的方法,await()是等待事情完成的线程用个方法,这两种线程是可以分开的(下面例子:CountdownLatchTest2),当然也可以是同一组线程;CyclicBarrier只有一个方法await(),指的是做事线程必须大家同时等待,必须是同一组线程的工作。
import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/*** 各个线程执行完成后,主线程做总结性工作的例子* @author xuexiaolei* @version 2017年11月02日*/public class CountdownLatchTest2 { private final static int THREAD_NUM = 10; public static void main(String[] args) { CountDownLatch lock = new CountDownLatch(THREAD_NUM); ExecutorService exec = Executors.newCachedThreadPool(); for (int i = 0; i < THREAD_NUM; i++) { exec.submit(new CountdownLatchTask(lock, "Thread-"+i)); } try { lock.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("大家都执行完成了,做总结性工作"); exec.shutdown(); } static class CountdownLatchTask implements Runnable{ private final CountDownLatch lock; private final String threadName; CountdownLatchTask(CountDownLatch lock, String threadName) { this.lock = lock; this.threadName = threadName; } @Override public void run() { System.out.println(threadName + " 执行完成"); lock.countDown(); } }}
CyclicBarrier例子:
import java.util.concurrent.*;/**** @author xuexiaolei* @version 2017年11月02日*/public class CyclicBarrierTest { private final static int THREAD_NUM = 10; public static void main(String[] args) { CyclicBarrier lock = new CyclicBarrier(THREAD_NUM, new Runnable() { @Override public void run() { System.out.println("这阶段大家都执行完成了,我总结一下,然后开始下一阶段"); } }); ExecutorService exec = Executors.newCachedThreadPool(); for (int i = 0; i < THREAD_NUM; i++) { exec.submit(new CountdownLatchTask(lock, "Task-"+i)); } exec.shutdown(); } static class CountdownLatchTask implements Runnable{ private final CyclicBarrier lock; private final String threadName; CountdownLatchTask(CyclicBarrier lock, String threadName) { this.lock = lock; this.threadName = threadName; } @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println(threadName + " 执行完成"); try { lock.await(); } catch (BrokenBarrierException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } }}
转载地址:http://pgqs.baihongyu.com/