如javadoc中所述,当我使用CompletableFuture.allOf()组合独立的可完成期货时,在将所有期货提供给该方法之后,它不能可靠地完成。
例如。:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Runnable dummyTask = () -> {
try {
Thread.sleep(200);
} catch (InterruptedException ignored) {
}
};
CompletableFuture<Void> f1 = CompletableFuture.runAsync(dummyTask);
CompletableFuture<Void> f2 = CompletableFuture.runAsync(dummyTask);
CompletableFuture[] all = {f1, f2};
f1.whenComplete((aVoid, throwable) -> System.out.println("Completed f1"));
f2.whenComplete((aVoid, throwable) -> System.out.println("Completed f2"));
CompletableFuture<Void> allOf = CompletableFuture.allOf(all);
allOf.whenComplete((aVoid, throwable) -> {
System.out.println("Completed allOf");
}
);
allOf.join();
System.out.println("Joined");
}
}
导致以下结果:
Completed f2
Joined
Completed allOf
Completed f1
我希望日志记录“Joined”和“Completed allOf”将在“Completed f1”和“Completed f2”之后编写。
使事情变得更加混乱的期货顺序似乎是头等大事。如果我换了线
CompletableFuture[] all = {f1, f2};
至
CompletableFuture[] all = {f2, f1};
结果输出变为:
Completed allOf
Completed f1
Completed f2
Joined
更糟糕的是,如果我多次运行完全相同的代码,顺序将再次更改。我可以理解,“f1”和“f2”的顺序是随机变化的,对于“allOf”和“Joined”同样如此。但这确实令人惊讶。
如果很重要:这是Windows 7上的JDK 1.8.0_91。
最佳答案
f1.whenComplete
返回一个独立于f1
的新 future 。 AllOf
将等待f1
完成,但不等待传递给whenComplete
的lambda完成。要获得想要的结果,您可以尝试类似的方法:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Runnable dummyTask = () -> {
try {
Thread.sleep(200);
} catch (InterruptedException ignored) {
}
};
CompletableFuture<Void> f1 = CompletableFuture.runAsync(dummyTask);
CompletableFuture<Void> f2 = CompletableFuture.runAsync(dummyTask);
f1 = f1.whenComplete((aVoid, throwable) -> System.out.println("Completed f1"));
f2 = f2.whenComplete((aVoid, throwable) -> System.out.println("Completed f2"));
CompletableFuture[] all = {f1, f2};
CompletableFuture<Void> allOf = CompletableFuture.allOf(all);
allOf.whenComplete((aVoid, throwable) -> {
System.out.println("Completed allOf");
});
allOf.join();
System.out.println("Joined");
}
}