CompletableFuture.allOf() 在个别期货后未完成
CompletableFuture.allOf() not completing after individual futures
当我使用 CompletableFuture.allOf() 来组合独立的可完成期货(如 javadoc 中所述)时,在向该方法提供所有期货后,它无法可靠地完成。
例如:
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" 也是如此。但这确实令人惊讶。
以防万一:这是 JDK 1.8.0_91 在 Windows 7.
没关系 - 没有人保证回调的顺序。
在 wenComplete 方法上调用 join
allOf.whenComplete((aVoid, throwable) -> {
System.out.println("Completed allOf");
}
).join();
f1.whenComplete
returns 独立于 f1
的新未来。 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");
}
}
当我使用 CompletableFuture.allOf() 来组合独立的可完成期货(如 javadoc 中所述)时,在向该方法提供所有期货后,它无法可靠地完成。 例如:
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" 也是如此。但这确实令人惊讶。
以防万一:这是 JDK 1.8.0_91 在 Windows 7.
没关系 - 没有人保证回调的顺序。
在 wenComplete 方法上调用 join
allOf.whenComplete((aVoid, throwable) -> {
System.out.println("Completed allOf");
}
).join();
f1.whenComplete
returns 独立于 f1
的新未来。 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");
}
}