600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 面试官:如何让主线程等待所有的子线程执行结束之后再执行

面试官:如何让主线程等待所有的子线程执行结束之后再执行

时间:2024-09-20 10:20:56

相关推荐

面试官:如何让主线程等待所有的子线程执行结束之后再执行

java 主线程等待所有子线程执行完毕在执行,在工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总(比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程来执行,所有处理完成了之后才会返回给用户下单成功)的场景, 这时候就需要使用线程了。

解决方法

sleep

用 sleep 方法,让主线程睡眠一段时间,让其它子线程先执行,虽然也是解决的方法,但是不推荐使用。

public class ThreadTest extends Thread {public static void main(String[] args) throws InterruptedException {for(int i = 0;i<10;i++) {Thread th = new Thread(new Runnable() {public void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("子线程先执行");}});th.start();}Thread.sleep(5000);System.out.println("主线程执行");}}

执行结果如下:

join()

使用 Thread 的 join() 等待所有的子线程执行完毕,主线程在执行,阻塞的是主线程。

public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {try {Thread.sleep(3000);System.out.println("子线程先执行");} catch (InterruptedException e) {e.printStackTrace();}});t1.start();Thread t2 = new Thread(() -> {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}});t2.start();//主线程其他工作完毕,等待子线程的结束, 调用join系列的方法即可t1.join();t2.join();System.out.println("主线程执行");}

isTerminated

isTerminated,当调用shutdown()方法后,并且所有提交的任务完成后才会返回为true

public static void main(String[] args) throws InterruptedException {ExecutorService pool = Executors.newFixedThreadPool(3);pool.execute(() -> {try {Thread.sleep(2000);System.out.println("子线程先执行");} catch (InterruptedException e) {e.printStackTrace();}});//不再接受新的任务pool.shutdown();while (true) {//不推荐(循环效率很低)if (pool.isTerminated()) {System.out.println("线程池中的任务执行结束");break;}}System.out.println("主线程执行");}

执行结果如下:

Future机制

public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService pool = Executors.newFixedThreadPool(3);Future<Integer> task = pool.submit(() -> {try {Thread.sleep(2000);System.out.println("子线程先执行");} catch (InterruptedException e) {e.printStackTrace();}return 2;});//不再接受新的任务pool.shutdown();//get方法为阻塞获取System.out.println("task的运行结果:" + task.get());System.out.println("主线程执行");}

执行结果如下:

CountDownLatch

每调用一次countDown方法,计数器会减1,在计数器减为0之前,await方法将会阻塞主线程。

public static void main(String[] args) throws InterruptedException, ExecutionException {CountDownLatch latch = new CountDownLatch(1);Thread thread = new Thread(() -> {try {Thread.sleep(3000);System.out.println("子线程先执行");} catch (InterruptedException e) {e.printStackTrace();} finally {latch.countDown();}});thread.start();latch.await();System.out.println("主线程");}

执行结果如下:

CompletableFuture

public static void main(String[] args) throws InterruptedException, ExecutionException {CompletableFuture<Integer> cf1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(2000);System.out.println("子线程先执行");} catch (InterruptedException e) {e.printStackTrace();}return 2;});CompletableFuture<Integer> cf = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(2000);System.out.println("子线程先执行");} catch (InterruptedException e) {e.printStackTrace();}return 3;}).thenCombine(cf1, (result1, result2) -> result1 * result2);//get方法为阻塞获取System.out.println("计算结果为" + cf.get());System.out.println("主线程执行");}

执行结果如下:

CyclicBarrier

public static void main(String[] args) throws InterruptedException, ExecutionException, BrokenBarrierException {final CyclicBarrier barrier = new CyclicBarrier(5);for(int i=0;i<5;i++) {Thread thread = new Thread(new Runnable() {public void run() {try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("子线程先执行");try {barrier.await();} catch (InterruptedException | BrokenBarrierException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});thread.start();}barrier.await();System.out.println("主线程执行");}

到这里小伙伴可能会问,countDownLatch 和 cyclicBarrier 有什么区别呢?不妨看一下我这篇文章: JUC下的CountDownLatch,CyclicBarrier、Semaphore的使用方法

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。