Java 等待第一个线程完成,然后并行运行其他线程
在我的主流程中,我想并行地完成一些任务。假设我有4个任务要在一个单独的流程中执行,但在这4个任务中,第一个任务需要完成,然后才能并行运行其他任务 我认为我的代码符合我的要求,但有更好的方法吗Java 等待第一个线程完成,然后并行运行其他线程,java,multithreading,parallel-processing,java-8,Java,Multithreading,Parallel Processing,Java 8,在我的主流程中,我想并行地完成一些任务。假设我有4个任务要在一个单独的流程中执行,但在这4个任务中,第一个任务需要完成,然后才能并行运行其他任务 我认为我的代码符合我的要求,但有更好的方法吗 public static void main(String[] args) { System.out.println("In main"); ExecutorService executor = Executors.newSingleThreadExecutor();
public static void main(String[] args) {
System.out.println("In main");
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
runParalleltasks();
});
executor.shutdown();
System.out.println("Exiting main");
}
private static void runParalleltasks() {
System.out.println("Running parallel tasks");
doTask1();
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(() -> {
doTask2();
});
executor.submit(() -> {
doTask3();
});
executor.submit(() -> {
doTask4();
});
executor.shutdown();
System.out.println("Exiting parallel tasks");
}
你可能想看看新设施。对于像您这样的小案例,它可能不会提供很多帮助,但它提供了很多灵活性:
import static java.util.concurrent.CompletableFuture.allOf;
import static java.util.concurrent.CompletableFuture.runAsync;
runAsync(() -> doTask1(), executor)
.thenCompose(v -> allOf(
runAsync(() -> doTask2(), executor),
runAsync(() -> doTask3(), executor),
runAsync(() -> doTask4(), executor)
));
如果您需要将task1的输出传递给相关任务,那么这种方法将真正发挥作用。假设doTask1
返回一个字符串
,而doTask2
接受一个字符串
。现在,对于第一个任务,我们应该使用supplyAsync
,而不是runAsync
:
supplyAsync(() -> doTask1(), executor)
.thenCompose(resultOf1 -> allOf(
runAsync(() -> doTask2(resultOf1), executor),
runAsync(() -> doTask3(), executor),
runAsync(() -> doTask4(), executor)
));
您也可以使用
ExecutorService
来实现这一点,就像您最初的方法一样。您只需使用submit
的结果即可完成后续任务:
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<?> task1 = executor.submit(() -> doTask1());
Stream.<Runnable>of(() -> doTask2(), () -> doTask3(), () -> doTask4())
.forEach(r -> executor.submit(() -> { try {
task1.get();
r.run();
} catch(InterruptedException|ExecutionException ex){}
}));
executor.shutdown();
为什么有单线程执行器?@matt,因为我想在独立于main的流中执行我的4个任务,但在这4个任务中,第一个任务需要在我可以并行运行其他任务之前完成。我永远不会理解为什么人们需要顺序执行时使用线程。显然,您应该内联运行第一个任务,然后生成其他三个任务。@EJP我需要在与main方法不同的流中执行我的4个任务,4个任务中的最后3个任务取决于第一个任务的输出。有人知道在哪里可以找到这个问题的答案,是可调用的而不是可运行的吗?但是这种方法将我的主要方法保留到完成为止。我需要在不等待这4个任务完成的情况下退出main。在这种情况下,main方法应该返回
CompletableFuture
,而不是join
ing。我编辑了答案以反映这一点。
for(Runnable r: Arrays.<Runnable>asList(() -> doTask2(), () -> doTask3(), () -> doTask4()))
executor.submit(() -> { try {
task1.get();
r.run();
} catch(InterruptedException|ExecutionException ex){}
});