单个线程等待:多个线程(任务)完成后,进行汇总合并
public class TestCountDownLatch1 { public static void main(String[] args) throws InterruptedException { int count = 3; CountDownLatch countDownLatch = new CountDownLatch(count); for (int i = 0; i < count; i++) { final int index = i; new Thread(() -> { try { Thread.sleep(1000 + ThreadLocalRandom.current().nextInt(1000)); System.out.println("finish" + index + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); }finally{ countDownLatch.countDown(); } }).start(); } countDownLatch.await();// 主线程在阻塞,当计数器==0,就唤醒主线程往下执行。 System.out.println("主线程:在所有任务运行完成后,进行结果汇总"); } }
这种场景应该是用的最多了,比如我们打开一个电商的个人中心页面,我们需要调用,用户信息接口、用户订单接口、用户会员信息等接口,然后合并后一起给到前端,假设每个接口最长耗时为1s
,如果我们同步调用的话最大耗时时间是3s,如果我们采用异步调用然后合并结果,所以最大的耗时时间是3s
。每个接口调用返回数据后调用countDown
方法,让计数器进行减1,当把计数器减为0时的这个线程会去唤醒主线程,让它继续往下走。
个人理解:
long start = System.currentTimeMillis(); int count = 3; CountDownLatch countDownLatch = new CountDownLatch(count); for (int i = 0; i < count; i++) { final int index = i; int finalI = i; new Thread(() -> { try { // Thread.sleep(1000 + ThreadLocalRandom.current().nextInt(1000)); if(0 == finalI){ T1(); } if(1 == finalI){ T2(); } if(2 == finalI){ T3(); } System.out.println("finish" + index + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); }finally{ countDownLatch.countDown(); } }).start(); } countDownLatch.await();// 主线程在阻塞,当计数器==0,就唤醒主线程往下执行。 System.out.println("主线程:在所有任务运行完成后,进行结果汇总"); System.out.println(System.currentTimeMillis()-start); } public void T1() throws InterruptedException { Thread.sleep(1000); System.out.println("T1"); } public void T2() throws InterruptedException { Thread.sleep(1000); System.out.println("T2"); } public void T3() throws InterruptedException { Thread.sleep(1000); System.out.println("T3"); }
执行结果
地址https://mp.weixin.qq.com/s/ga3x8LYxDMgCzdfn6UUT_w