当前位置: 首页 > 后端技术 > Java

等待所有子线程完成后再进行的多种Java方法

时间:2023-04-01 18:33:06 Java

介绍在现实世界中,我们经常需要等待其他任务完成后再进行下一步。有很多方法可以实现Java等待子线程完成后再继续执行。让我们一一过一遍。Thread的join方法Thread提供了这个方法。当调用join()时,主线程会被阻塞,直到Thread执行完毕才会继续执行。代码如下:privatestaticvoidthreadJoin(){Listthreads=newArrayList<>();对于(inti=0;i{try{t.join();}catch(InterruptedExceptione){thrownewRuntimeException(e);}});System.out.println("threadJoinFinishedAllTasks...");}结果:任务6正在运行任务9正在运行任务3正在运行任务4正在运行任务7正在运行任务0正在运行任务2正在运行任务1正在运行任务5正在运行任务8正在运行runningTask1完成Task8完成Task6完成Tasklet4完成Tasked3is0完成Task7完成Task9完成Task2完成Task5完成threadJoinFinishedAllTasks...CountDownLatchCountDownLatch是一个很好用的并发工具,线程数应该在初始化时指定,比如10。当子线程调用countDown()时,计数减1。在它为0之前,await()方法不会阻塞。代码如下:privatestaticvoidcountDownLatch(){CountDownLatchlatch=newCountDownLatch(NUM);for(inti=0;i{System.out.println("countDownLatchrunning...");try{Thread.sleep(1000);System.out.println("countDownLatchFinished...");latch.countDown();}catch(InterruptedExceptione){thrownewRuntimeException(e);}});t.开始();}尝试{latch.await();}catch(InterruptedExceptione){thrownewRuntimeException(e);}System.out.println("countDownLatchFinishedAllTasks...");}结果:countDownLatchrunning...countDownLatchrunning...countDownLatchrunning...countDownLatchrunning...countDownLatchrunning...countDownLatchrunning...countDownLatch正在运行...countDownLatch正在运行...countDownLatch正在运行...countDownLatch正在运行...countDownLatch已完成...countDownLatch已完成...countDownLatchFinished...countDownLatchFinished...countDownLatchFinished...countDownLatchFinished...countDownLatchFinished...countDownLatchFinished...countDownLatchFinished...countDownLatchFinished...countDownLatchFinishedAllTasks...CyclicBarrierCyclicBarrier与CountDownLatch类似,但CyclicBarrier可重新设置,可重新使用代码如下:privatestaticvoidcyclicBarrier(){CyclicBarrierbarrier=newCyclicBarrier(NUM+1);for(inti=0;i{System.out.println("cyclicBarrierrunning...");try{Thread.sleep(1000);System.out.println("cyclicBarrierFinished...");barrier.await();}catch(InterruptedException|BrokenBarrierExceptione){thrownewRuntimeException(e);}});t.开始();}尝试{barrier.await();}catch(InterruptedException|BrokenBarrierExceptione){thrownewRuntimeException(e);}System.out.println("cyclicBarrierFinishedAllTasks...");}结果:cyclicBarrierrunning...cyclicBarrierrunning...cyclicBarrierrunning...cyclicBarrierrunning...cyclicBarrierrunning...cyclicBarrierrunning...cyclicBarrierrunning...cyclicBarrierrunning...cyclicBarrierrunning...cyclicBarrierrunning...cyclicBarrierFinished...cycicBarrier已完成...cyclicBarrier已完成...cyclicBarrier已完成...cyclicBarrier已完成...cyclicBarrier已完成...cyclicBarrier已完成...cyclicBarrier已完成...cyclicBarrier已完成...cyclicBarrier已完成...cyclicBarrier已完成所有任务。..executorService.isTerminated()ExecutorService调用shutdown()方法后,可以通过isTerminated()方法判断任务是否完成代码如下:privatestaticvoidexecuteServiceIsTerminated(){ExecutorServiceexecutorService=Executors.newFixedThreadPool(THREADS);IntStream.range(0,NUM).forEach(i->executorService.execute(newPkslowTask("任务"+i)));executorService.shutdown();while(!executorService.isTerminated()){//waiting...}System.out.println("executeServiceIsTerminatedFinishedAllTasks...");}结果:任务0正在运行任务2正在运行任务1正在运行任务3正在运行任务4正在运行任务0已完成任务2已完成任务5正在运行任务4已完成任务7正在运行任务3已完成任务1已完成任务8正在运行任务6正在运行任务9正在运行任务5已完成任务9已完成任务7已完成任务6已完成任务8已完成executeServiceIsTerminatedFinishedAllTasks...executorService.awaitTerminationexecutorService.awaitTermination方法会等任务完成,并给一个超时时间,代码如下:privatestaticvoidexecuteServiceAwaitTermination(){ExecutorServiceexecutorService=Executors.newFixedThreadPool(THREADS);IntStream.range(0,NUM).forEach(i->executorService.execute(newPkslowTask("任务"+i)));executorService.shutdown();尝试{if(!executorService.awaitTermination(1,TimeUnit.MINUTES)){executorService.shutdownNow();}}catch(InterruptedExceptione){thrownewRuntimeException(e);}System.out.println("executeServiceAwaitTerminationFinishedAllTasks...");}结果:任务0正在运行任务1正在运行任务2正在运行任务3正在运行任务4正在运行任务0已完成任务5正在运行任务1已完成任务4已完成任务7正在运行任务3已完成任务8正在运行任务2已完成任务9正在运行任务6正在运行任务5已完成任务7已完成任务9已完成任务8已完成任务6已完成executeServiceAwaitTerminationFinishedAllTasks...executorService.invokeAll使用invokeAll提供所有服务,代码如下:优先级vatestaticvoidexecuteServiceInvokeAll(){ExecutorServiceexecutorService=Executors.newFixedThreadPool(线程);List>tasks=newArrayList<>();IntStream.range(0,NUM).forEach(i->tasks.add(newPkslowTask("任务"+i)));尝试{executorService.invokeAll(任务);}catch(InterruptedExceptione){thrownewRuntimeException(e);}executorService.shutdown();System.out.println("executeServiceInvokeAllFinishedAllTasks...");}结果:任务1正在运行任务2正在运行任务0正在运行任务3正在运行任务4正在运行任务1已完成任务3已完成任务0已完成任务2已完成任务4正在运行已完成任务8正在运行任务5正在运行任务6正在运行任务9正在运行任务7正在运行任务8已完成任务5已完成任务6已完成任务9已完成任务7已完成executeServiceInvokeAll已完成所有任务...ExecutorCompletionServiceExecutorCompletionS服务通过take()方法,会返回最早完成的任务,代码如下:privatestaticvoidexecutorCompletionService(){ExecutorServiceexecutorService=Executors.newFixedThreadPool(10);CompletionServiceservice=newExecutorCompletionService<>(executorService);List>callables=newArrayList<>();callables.add(newDelayedCallable(2000,"2000ms"));callables.add(newDelayedCallable(1500,"1500ms"));callables.add(newDelayedCallable(6000,"6000ms"));callables.add(newDelayedCallable(2500,"2500ms"));callables.add(newDelayedCallable(300,"300ms"));callables.add(newDelayedCallable(3000,"3000ms"));callables.add(newDelayedCallable(1100,"1100ms"));callables.add(newDelayedCallable(100,"100ms"));callables.add(newDelayedCallable(100,"100ms"));callables.add(newDelayedCallable(100,"100ms"));callables.for每个(服务::提交);for(inti=0;ifuture=service.take();System.out.println(future.get()+"任务完成");}catch(InterruptedException|ExecutionExceptione){thrownewRuntimeException(e);}}System.out.println("executorCompletionService完成所有任务...");executorService.shutdown();awaitTerminationAfterShutdown(executorService);}这里不同任务的时长是不一样的,但会先返回最早完成的任务:2000msisrunning2500msisrunning300msisrunning1500msisrunning6000msisrunning3000msisrunning1100msisrunning100msisrunning100msisrunning100msisrunning100msiscompleted100msiscompleted100ms任务完成100ms任务完成100ms完成100ms任务完成300ms完成300ms任务完成1100ms完成1100ms任务完成1500ms完成1500ms任务完成2000ms完成2000ms任务完成2500ms完成2500ms任务完成3000ms完成3000ms任务完成6000ms完成6000ms任务完成executorCompletionServiceFinishedAllTasks...代码代码请看GitHub:https://github.com/LarryDpk/pkslow-samples