CompletableFuture<ResponseList> stsTask = CompletableFuture.supplyAsync(() -> this.stsCompute(question);
CompletableFuture<ResponseList> dssmTask = CompletableFuture.supplyAsync(() -> this.dssmCompute(question);
// Is this line unnecessary?
CompletableFuture<Void> twoFutures = CompletableFuture.allOf(stsTask, dssmTask);
try {
ResponseList stsList = stsTask.get();
ResponseList dssmList = dssmTask.get();
// after the two are done, proceed here
processResult(stsList, dssmList)
} catch(Exception e){
// do something
}
我有两个问题:
get()
方法等待它完成而必须在dssmTask之前执行stsTask?变量'twoFutures'未使用。CompletableFuture.allOf(stsTask, dssmTask)
行是不必要还是必要?答案 0 :(得分:1)
如果您未在get
上调用twoFutures
,则该行是多余的。
如果要等待它们都完成后再对结果进行处理,则应按以下方式重构代码:
stsTask.thenAcceptBoth(dssmTask, (stsResult, dssmResult) -> {
ResponseList stsList = stsResult; // or stsTask.get()
ResponseList dssmList = dssmResult; // or dssmTask.get()
// ...
});
答案 1 :(得分:1)
是的,如果您的公共fork / join池中有足够的线程,它们将同时执行。 allOf
方法返回新的CompletableFuture
,当所有给定的CompletableFutures
完成时,新的future.get()
完成。但是您没有任何合并结果的工具,因此这里不需要。
这里要考虑的另一点是调用stsTask.thenCombine(dssmTask, (stsList, dssmList) -> processResult(stsList, dssmList));
方法以获取结果。此方法调用处于阻塞状态,将使您的调用线程保持阻塞状态。
所以这是一种更好的方法,
low
答案 2 :(得分:-1)
在不确定多线程任务执行路径时使用记录器:
private static Logger logger = getLogger(S.class);
public static void main(String[] args) {
CompletableFuture<List> stsTask = CompletableFuture.supplyAsync(() -> {
logger.info("running");
return new ArrayList();
});
CompletableFuture<List> dssmTask = CompletableFuture.supplyAsync(() -> {
logger.info("running");
return new ArrayList();
});
// Is this line unnecessary?
CompletableFuture<Void> twoFutures = CompletableFuture.allOf(stsTask, dssmTask);
logger.info("twoFutures is completed? " + twoFutures.isDone());
logger.info("allof dose not wait task to complete, just to check if all the task is completed, so this is unnecessary");
try {
List stsList = stsTask.get();
logger.info("stsList completed? " + stsTask.isDone());
List dssmList = dssmTask.get();
logger.info("dssmList completed? " + dssmTask.isDone());
logger.info("get() will block until task is done");
// after the two are done, proceed here
// processResult(stsList, dssmList)
} catch (Exception e) {
// do something
}
}
outPut:
15:18:28.791 [main] INFO cn.lihongjie.S - twoFutures is completed? false
15:18:28.791 [ForkJoinPool.commonPool-worker-2] INFO cn.lihongjie.S - running
15:18:28.791 [ForkJoinPool.commonPool-worker-1] INFO cn.lihongjie.S - running
15:18:28.794 [main] INFO cn.lihongjie.S - allof dose not wait task to complete, just to check if all the task is completed, so this is unnecessary
15:18:28.795 [main] INFO cn.lihongjie.S - stsList completed? true
15:18:28.795 [main] INFO cn.lihongjie.S - dssmList completed? true
15:18:28.795 [main] INFO cn.lihongjie.S - get will block until task is done
我使用logback logger,默认情况下它将打印线程名称,此问题很方便。
任务是同时执行的,有两个线程在运行它
15:18:28.791 [ForkJoinPool.commonPool-worker-2] INFO cn.lihongjie.S - running
15:18:28.791 [ForkJoinPool.commonPool-worker-1] INFO cn.lihongjie.S - running
allOf
是不必要的,直到所有任务完成后,此调用才会阻塞。您可以通过查看日志来找出答案。