当前位置 : 主页 > 编程语言 > java >

面试官:多个线程执行完毕后,才执行另一个线程,该怎么做?

来源:互联网 收集:自由互联 发布时间:2022-08-10
CountDownLatch 去掉try catch版本 public static void main ( String [] args ) throws InterruptedException { /** * Thread-1 在路上耗时4秒 * Thread-2 在路上耗时0秒 * Thread-0 在路上耗时4秒 * Thread-2 到达车站了 * Thre


面试官:多个线程执行完毕后,才执行另一个线程,该怎么做?_重置

CountDownLatch

去掉try catch版本

public static void main(String[] args) throws InterruptedException {

/**
* Thread-1 在路上耗时4秒
* Thread-2 在路上耗时0秒
* Thread-0 在路上耗时4秒
* Thread-2 到达车站了
* Thread-1 到达车站了
* Thread-0 到达车站了
* 老司机,发车
*/
CountDownLatch countDownLatch = new CountDownLatch(3);
Random random = new Random();
for (int i = 0; i < 3; i++) {
new Thread(() -> {
//返回[0,5)的值
int time = random.nextInt(5);
System.out.println(Thread.currentThread().getName() + " 在路上耗时" + time + "秒");
TimeUnit.SECONDS.sleep(time);
System.out.println(Thread.currentThread().getName() + " 到达车站了");
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
System.out.println("老司机,发车");
}

先来演示一下用法,可以看到所有子线程都执行完毕才会执行主线程。实现这个功能主要靠的是CountDownLatch的2个方法await()和countDown()。

new一个CountDownLatch时会传一个计数器的值,上面的例子为3。调用await()方法时判断计数是否为0,如果不为0则呈等待状态。其他线程可以调用countDown()方法将计数减1,当计数减到位0时,则呈等待的线程继续执行。

CyclicBarrier

去掉try catch版本

public static void main(String[] args) {

/**
* Thread-1 在路上耗时0秒
* Thread-2 在路上耗时2秒
* Thread-1 到达车站了
* Thread-0 在路上耗时3秒
* Thread-2 到达车站了
* Thread-0 到达车站了
* 老司机,发车
*/
CyclicBarrier cyclicBarrier = new CyclicBarrier(3, ()->{
System.out.println("老司机,发车");
});
Random random = new Random();
for (int i = 0; i < 3; i++) {
new Thread(() -> {
//返回[0,5)的值
int time = random.nextInt(5);
System.out.println(Thread.currentThread().getName() + " 在路上耗时" + time + "秒");
TimeUnit.SECONDS.sleep(time);
System.out.println(Thread.currentThread().getName() + " 到达车站了");
cyclicBarrier.await();
}).start();
}
}

CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset()方法重置。挺简单的就不再演示。因为这2个工具类都用到了AQS,而AQS的原理很长,因此在本文就不介绍AQS的实现了

CompletableFuture

去掉try catch版本

public static void main(String[] args) {
/**
* ForkJoinPool.commonPool-worker-1 在路上耗时4秒
* ForkJoinPool.commonPool-worker-2 在路上耗时3秒
* ForkJoinPool.commonPool-worker-1 到达车站了
* ForkJoinPool.commonPool-worker-2 到达车站了
* 老司机,发车
*/
Random random = new Random();
CompletableFuture future1 = CompletableFuture.runAsync(() -> {
int time = random.nextInt(5);
System.out.println(Thread.currentThread().getName() + " 在路上耗时" + time + "秒");
TimeUnit.SECONDS.sleep(random.nextInt());
System.out.println(Thread.currentThread().getName() + " 到达车站了");
});
CompletableFuture future2 = CompletableFuture.runAsync(() -> {
int time = random.nextInt(5);
System.out.println(Thread.currentThread().getName() + " 在路上耗时" + time + "秒");
TimeUnit.SECONDS.sleep(random.nextInt());
System.out.println(Thread.currentThread().getName() + " 到达车站了");
});
CompletableFuture.allOf(future1, future2).thenRun(() -> {
System.out.println("老司机,发车");
});
}

参考博客

https://www.jianshu.com/p/2808c93fef12


上一篇:Java入门必读
下一篇:没有了
网友评论