java CompletableFuture未按预期工作
我试图从Java8理解CompletableFuture
的工作原理。下面的代码按预期工作
CompletableFuture.supplyAsync(() -> {
System.out.println("supplyAsync Thread name " + Thread.currentThread().getName());
return "str";
}).thenApply(str -> {
System.out.println("thenApply Thread name " + Thread.currentThread().getName());
return str;
}).thenApply(str1 -> {
System.out.println("thenApply Thread name " + Thread.currentThread().getName());
return str1;
}).thenAccept(str3 -> {
System.out.println("thenAccept Thread name " + Thread.currentThread().getName());
});
System.out.println("Thread name " + Thread.currentThread().getName());
输出:
supplyAsync Thread name ForkJoinPool.commonPool-worker-1
thenApply Thread name main
thenApply Thread name main
thenAccept Thread name main
Thread name main
但是当我进行一些计算时,它并没有像预期的那样工作。如果我遗漏了什么,请纠正我
CompletableFuture.supplyAsync(() -> {
System.out.println("supplyAsync Thread name " + Thread.currentThread().getName());
long val = 0;
for (long i = 0; i < 1000000; i++) {
val++;
}
return "str";
}).thenApply(str -> {
System.out.println("thenApply Thread name " + Thread.currentThread().getName());
long val = 0;
for (long i = 0; i < 1000000; i++) {
val++;
}
return str;
}).thenApply(str1 -> {
System.out.println("thenApply Thread name " + Thread.currentThread().getName());
long val = 0;
for (long i = 0; i < 1000000; i++) {
val++;
}
return str1;
}).thenAccept(str3 -> {
System.out.println("thenAccept Thread name " + Thread.currentThread().getName());
long val = 0;
for (long i = 0; i < 1000000; i++) {
val++;
}
});
System.out.println("Thread name " + Thread.currentThread().getName());
输出为:
supplyAsync Thread name ForkJoinPool.commonPool-worker-1
Thread name main
我同意我没有将子线程连接到主线程。我的理解是子线程应该独立于主线程打印语句。问题是为什么它根本不打印
# 1 楼答案
解释
您没有将子线程
ForkJoinPool.commonPool-worker-1
连接到主线程。所以一旦线程main
完成,它就会被杀死解决方案
在代码中的某个时刻,尝试调用
.join()
来描述你的完全未来。请注意,此方法正在阻止main
线程。因此,连接点之后的执行将暂停,直到子线程完成其执行将打印:
如果希望最后一个
System.out.println(...)
不依赖于子线程的执行,则将CompletableFuture
分配给一个变量,并将其连接到main的最末端:# 2 楼答案
你的理解是错误的
每the documentation
这并不要求依赖完成由完成异步操作的线程执行,它只允许它
不过,我同意另一个答案,即你应该安排在计算链完成之前不要退出主例程