Java 这两项任务是否同时执行? CompletableFuture stsTask=CompletableFuture.supplyAsync(()->this.stscocomputer(问题); CompletableFuture dssmTask=CompletableFuture.supplyAsync(()->this.dssmCompute(问题); //这行没有必要吗? CompletableFuture twoFutures=CompletableFuture.allOf(stsTask,dssmTask); 试一试{ ResponseList stsList=stsTask.get(); ResponseList dssmList=dssmTask.get(); //完成这两个步骤后,继续此处 processResult(strList、dssmList) }捕获(例外e){ //做点什么 }
我有两个问题:Java 这两项任务是否同时执行? CompletableFuture stsTask=CompletableFuture.supplyAsync(()->this.stscocomputer(问题); CompletableFuture dssmTask=CompletableFuture.supplyAsync(()->this.dssmCompute(问题); //这行没有必要吗? CompletableFuture twoFutures=CompletableFuture.allOf(stsTask,dssmTask); 试一试{ ResponseList stsList=stsTask.get(); ResponseList dssmList=dssmTask.get(); //完成这两个步骤后,继续此处 processResult(strList、dssmList) }捕获(例外e){ //做点什么 },java,completable-future,concurrent.futures,Java,Completable Future,Concurrent.futures,我有两个问题: 这两个任务是同时执行的吗?或者stsTask必须在dssmTask之前执行,因为get()方法要等待它完成吗?不使用变量“twoFutures” 行CompletableFuture.allOf(stsTask,dssmTask)是不必要的还是必要的 如果未在twootures上调用get,则该行是多余的 如果您想等待它们都完成,然后对结果进行处理,您应该按照如下方式重构代码: CompletableFuture<ResponseList> stsTask = Com
get()
方法要等待它完成吗?不使用变量“twoFutures”CompletableFuture.allOf(stsTask,dssmTask)
是不必要的还是必要的如果未在
twootures
上调用get
,则该行是多余的
如果您想等待它们都完成,然后对结果进行处理,您应该按照如下方式重构代码:
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
}
当您不确定多线程任务执行路径时,请使用记录器:
stsTask.thenAcceptBoth(dssmTask, (stsResult, dssmResult) -> {
ResponseList stsList = stsResult; // or stsTask.get()
ResponseList dssmList = dssmResult; // or dssmTask.get()
// ...
});
我使用logback logger,默认情况下它会打印线程名称,这对于这个问题很方便
15:18:28.791[ForkJoinPool.commonPool-worker-2]信息cn.lihongjie.S-正在运行
15:18:28.791[ForkJoinPool.commonPool-worker-1]信息cn.lihongjie.S-正在运行
allOf
是不必要的,在所有任务完成之前,此调用不会阻塞。您可以通过查看日志来了解是的,如果您的公共fork/join池中有足够的线程,它们将同时执行。
allOf
方法返回一个新的CompletableFuture
,当所有给定的CompletableFutures
完成时,该方法将完成。但是您没有任何工具来合并结果,因此这里不需要它
这里考虑的另一点是调用<代码> Eng.For()(代码)>方法来获得结果。此方法调用是阻塞的,并且将保持调用线程处于阻塞状态。
所以这里有一个更好的方法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
听起来你不关心proceResult的返回值,那么为什么要使用Get?这将阻止线程。这里没有完全未来的实际用途。也可以使用Get-use-join()代替Get-use-join(),后者也是阻止但更干净的方法,没有try-catch。我会说allOf().join().run(()->processResult)我希望stsTask和dssmTask同时执行以提高速度。这是主要目的。所以它们实际上是同时执行的?所以我不需要做任何修改modification@user697911对
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
stsTask.thenCombine(dssmTask, (stsList, dssmList) -> processResult(stsList, dssmList));