CompletableFuture.allOf()未在个别期货后完成

时间:2017-11-21 16:40:45

标签: java completable-future

当我使用CompletableFuture.allOf()来组合javadoc中描述的独立可完成期货时,在提供给方法的所有期货之后它不能可靠地完成。 E.g:

Completed f2
Joined
Completed allOf
Completed f1

导致以下结果:

CompletableFuture[] all = {f1, f2};

我希望在“Completed f1”和“Completed f2”之后写入“Joined”和“Completed allOf”。 为了让事情更加混乱,数组中未来的顺序似乎是最重要的。如果我改变了行

CompletableFuture[] all = {f2, f1};

Completed allOf
Completed f1
Completed f2
Joined

结果输出变为:

DROP TABLE IF EXISTS A;

CREATE TABLE A
(num int,
 id int,
 col1 int);

 INSERT INTO A VALUES (1,     100,     0);
 INSERT INTO A VALUES (2,     100,     1);
 INSERT INTO A VALUES (3,     100,     0);
 INSERT INTO A VALUES (1,     101,     1);
 INSERT INTO A VALUES (2,     101,     1);
 INSERT INTO A VALUES (3 ,    101,     0);

DROP TABLE IF EXISTS B;

 CREATE TABLE B
(idx int,
 id int,
 col2 int);

 INSERT INTO B VALUES (1,     100,     20);
 INSERT INTO B VALUES (2,     100,     20);
 INSERT INTO B VALUES (3,     100,     20);
 INSERT INTO B VALUES (4,     101,     100);
 INSERT INTO B VALUES (5,     101,     100);

DROP TABLE IF EXISTS C;

CREATE TABLE C
(idx int,
 id int,
 col3 int);

 INSERT INTO C VALUES (1,     100,     1);
 INSERT INTO C VALUES (2,     100,     1);
 INSERT INTO C VALUES (3,     100,     1);
 INSERT INTO C VALUES (4,     101,     10);
 INSERT INTO C VALUES (5,     101,     1);

更糟糕的是,如果我多次运行完全相同的代码,则订单会再次发生变化。我可以理解“f1”和“f2”的顺序是随机变化的,同样也是“allOf”和“Joined”的变化。但这真的很令人惊讶。

如果重要:这是Windows 7上的JDK 1.8.0_91。

3 个答案:

答案 0 :(得分:4)

f1.whenComplete返回与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");
    }
}

答案 1 :(得分:0)

这没关系 - 没有人保证回调的顺序。

答案 2 :(得分:-1)

在wenComplete方法上调用join

allOf.whenComplete((aVoid, throwable) -> {
                System.out.println("Completed allOf");
            }
    ).join();