gpt4 book ai didi

java - 为什么我的线程不等待 CompletableFutures 完成 `allOf()` ?

转载 作者:行者123 更新时间:2023-12-02 02:56:59 25 4
gpt4 key购买 nike

我正在学习 Java 1.8 中的 CompletableFuture,但在尝试理解 allOf 时遇到了困难。主线程似乎不会等待任何 CompletableFuture 完成。

参见https://github.com/nurkiewicz/reactive/blob/master/src/test/java/be/more/reactive/S03_AllOf.java对于我正在测试的示例。

测试作业在打印任何结果之前完成。

有两种(丑陋?)方法可以避免这种情况:1)在主线程上设置超时并等待两者都完成。 2)最后设置一个.get(),它将成为一个阻塞任务。

这是为什么?

代码片段:

package be.more.reactive;

import be.more.reactive.util.BaseTest;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CompletableFuture;

public class S03_AllOf extends BaseTest {

private static final Logger log = LoggerFactory.getLogger(S03_AllOf.class);

private final CompletableFuture<String> futureResult1 = getFutureQueryResult("1"); //.exceptionally() ??
private final CompletableFuture<String> futureResult2 = getFutureQueryResult("2");
private final CompletableFuture<String> futureResult3 = getFutureQueryResult("3");
private final CompletableFuture<String> futureResult4 = getFutureQueryResult("4");

@Test
public void allOf() throws Exception {
final CompletableFuture<Void> futureResult = CompletableFuture.allOf( //Void ?? I want List<String>
futureResult1, futureResult2, futureResult3, futureResult4
);

// futureResult.thenAccept((Void vd) -> vd.??) //no, it won't work

futureResult.thenRun(() -> {
try {
log.debug("Query result 1: '{}'", futureResult1.get());
log.debug("Query result 2: '{}'", futureResult2.get());
log.debug("Query result 3: '{}'", futureResult3.get());
log.debug("Query result 4: '{}'", futureResult4.get()); //a lot of manual work

log.debug("Now do on complete"); //handling onComplete
} catch (Exception e) {
log.error("", e);
}
});

}

}

在 BaseTest 中:

protected CompletableFuture<String> getFutureQueryResult(final String queryId) {
return CompletableFuture.supplyAsync(
() -> db.apply(new Query(queryId))

);
}

在 DB.java 中

package be.more.reactive.db;

import java.util.concurrent.TimeUnit;

import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.apache.commons.lang3.RandomUtils.nextInt;
import static org.apache.commons.lang3.RandomUtils.nextLong;

public class DB {
public String apply(Query query) {
try {
TimeUnit.SECONDS.sleep(nextLong(2, 4));
} catch (InterruptedException e) {
e.printStackTrace();
}
return String.format("%s_%s", randomAlphabetic(nextInt(4, 12)), query.getId());
}
}

最佳答案

来自 Javadoc

Returns a new CompletableFuture that is completed when all of the given CompletableFutures complete.

Future 是一个异步任务,在您调用 get 之前不会阻塞(仅当任务仍在运行时才会阻塞)。

在这种情况下,CompleteableFuture 是所有 CompletableFuture 的复合 Future。这个 future 仍然是一个阻塞异步调用,您必须调用 getjoin 来等待所有 future 完成。再次,来自 javadoc

CompletableFutures before continuing a program, as in: CompletableFuture.allOf(c1, c2, c3).join();.

在我看来,你的(2)解决方案既不难看,也没有意想不到的功能。

关于java - 为什么我的线程不等待 CompletableFutures 完成 `allOf()` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42929866/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com