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

网友投稿 861 2022-10-24

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

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

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://jianshu.com/p/2808c93fef12

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Peridot - 一个事件驱动的测试框架
下一篇:YuiHatano —— 轻量级Android DAO单元测试框架
相关文章

 发表评论

暂时没有评论,来抢沙发吧~