单个线程等待:多个线程(任务)完成后,进行汇总合并
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