我正在寻找一个很好的解决方案来协调多个多线程任务。
基本上我有2个任务,我调用A
和B
,它们需要在与主线程不同的线程上执行。
但是B
必须在A
完成之后开始。 A
和B
本身包含应并行运行的几个部分,称为A1, A2, ... B1, B2, ...
。
并且有一个来自外部的呼叫者,无论进度如何,都需要重新启动整个作业。我该如何存档?我考虑过创建一种布尔数组,该数组用于保存信息(如果每个子任务(A1,...)已经完成,如果已经完成,则启动B。然后检查每个方法中的每行代码是否已经取消)。
但是在我看来,这不是一个优雅的解决方案,并且有办法很好地协调这一点。
最佳答案
在Java8中,可以使用CompletableFutures。方法execA
引发三个并行任务,并返回一个由所有这些任务组成的CompletableFuture。 execB
等待此复合任务完成,然后启动它自己的一组任务。最后,main方法中的get
等待B方法完成。
public class Futures {
String name;
int value;
public static void main(String[] args) {
try {
execB(execA()).get();
} catch(InterruptedException|ExecutionException e) {}
}
Futures(String name, int value) {
this.name = name;
this.value = value;
}
void runMethod() {
System.out.println("Entering " + name);
try {
Thread.sleep(value * 1000);
} catch(InterruptedException e) {}
System.out.println("Exiting " + name);
}
public static CompletableFuture<Void> execA() {
return(
CompletableFuture.<Void>allOf(
CompletableFuture.runAsync(() -> (new Futures("a1", 4)).runMethod()),
CompletableFuture.runAsync(() -> (new Futures("a2", 2)).runMethod()),
CompletableFuture.runAsync(() -> (new Futures("a3", 1)).runMethod()))
);
}
public static CompletableFuture<Void> execB(CompletableFuture<Void> prev) {
try {
prev.get();
} catch (InterruptedException|ExecutionException e) {}
return(
CompletableFuture.<Void>allOf(
CompletableFuture.runAsync(() -> (new Futures("b1", 2)).runMethod()),
CompletableFuture.runAsync(() -> (new Futures("b2", 3)).runMethod()),
CompletableFuture.runAsync(() -> (new Futures("b3", 1)).runMethod())));
}
}