Java CompletableFuture join()调用挂起主线程。个人的未来永远不会完成
我正在编写一个函数,创建多(7)个CompletableFutures。这些期货基本上都有两件事:Java CompletableFuture join()调用挂起主线程。个人的未来永远不会完成,java,completable-future,Java,Completable Future,我正在编写一个函数,创建多(7)个CompletableFutures。这些期货基本上都有两件事: 使用SupplySync(),从某些数据库获取数据 使用Accept()将此数据写入CSV文件 当所有7个futures都完成任务后,我想继续执行进一步的代码。因此,我使用allOf()并对allOf()返回的Void CompletableFuture调用一个join() 问题是,即使在执行了所有futures(我可以看到CSV正在生成)之后,join()调用仍然被卡住,进一步的代码执行将永远被
公共客户响应流程(){
CustomResponse msgResponse=新CustomResponse();
试一试{
//1.数据库调用1
CompletableFuture f1=dataHelper.fetchAndUploadCSV1();
//2.DbCall 2
CompletableFuture f2=dataHelper.fetchAndUploadCSV2();
//3.DbCall 3
CompletableFuture f3=dataHelper.fetchAndUploadCSV3();
//4.DbCall 4
CompletableFuture f4=dataHelper.fetchAndUploadCSV4();
//5.DbCall 5
CompletableFuture f5=dataHelper.fetchAndUploadCSV5();
//6.DB6
CompletableFuture f6=dataHelper.fetchAndUploadCSV6();
//7.DB7
CompletableFuture f7=dataHelper.fetchAndUploadCSV7();
CompletableFuture[]fAll=新的CompletableFuture[]{f1、f2、f3、f4、f5、f6、f7};
CompletableFuture.allOf(fAll.join();
msgressponse.setProcessed(true);
msgressponse.setMessageStatus(“消息”);
}捕获(例外e){
msgressponse.setMessageStatus(错误);
msgressponse.setErrorMessage(“错误”);
}
返回msgResponse;
}
每个fetchAndUploadCSV()函数如下所示:
public CompletableFuture fetchAndUploadCSV1(){
返回CompletableFuture.SupplySync(()->{
试一试{
返回someService().getAllData1();
}捕获(例外e){
抛出新的运行时异常(e);
}
})。然后接受(结果->{
试一试{
如果(results.size()>0){
上传ASCSV(结果);
}
否则{
log.info(“未找到任何数据”);
}
}捕获(例外e){
抛出新的运行时异常(e);
}
});
}
这就是csvWriter.uploadAsCsv(结果)
的样子-
public void uploadAsCsv(List objectList)引发异常{
long objListSize=((objectList==null)?0:objectList.size();
log.info(“Action=Start,objectListSize=“+objListSize”);
ByteArrayInputStream inputStream=getCsvAsInputStream(对象列表);
Info fileInfo=someClient.uploadFile(inputStream);
log.info(“Action=Done,FileInfo=“+((FileInfo==null?null:FileInfo.getID())));
}
我在这里使用OpenCSV将数据转换为CSV流。我总能看到最后一行日志
预期成果:
获取的所有数据、生成的CSV和CustomResponse都应返回为已处理状态,且无错误消息
实际结果:
获取所有数据、生成CSV并挂起主线程。您可以对每个已创建的
CompletableFuture
使用join
,而不牺牲并发性:
public CustomResponse process() {
CustomResponse msgResponse = new CustomResponse();
List<CompletableFuture<Void>> futures = Arrays.asList(dataHelper.fetchAndUploadCSV1(),
dataHelper.fetchAndUploadCSV2(),
dataHelper.fetchAndUploadCSV3(),
dataHelper.fetchAndUploadCSV4(),
dataHelper.fetchAndUploadCSV5(),
dataHelper.fetchAndUploadCSV6(),
dataHelper.fetchAndUploadCSV7());
return CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0]))
.thenApply(v -> {
msgResponse.setProcessed(true);
msgResponse.setMessageStatus("message");
return msgResponse;
})
.exceptionally(throwable -> {
msgResponse.setMessageStatus("ERROR");
msgResponse.setErrorMessage("error");
return msgResponse;
}).join();
}
公共客户响应流程(){
CustomResponse msgResponse=新CustomResponse();
List futures=Arrays.asList(dataHelper.fetchAndUploadCSV1(),
dataHelper.fetchAndUploadCSV2(),
dataHelper.fetchAndUploadCSV3(),
dataHelper.fetchAndUploadCSV4(),
dataHelper.fetchAndUploadCSV5(),
dataHelper.fetchAndUploadCSV6(),
dataHelper.fetchAndUploadCSV7());
return CompletableFuture.allOf(futures.toArray(新的CompletableFuture[0]))
。然后应用(v->{
msgressponse.setProcessed(true);
msgressponse.setMessageStatus(“消息”);
返回msgResponse;
})
.例外情况下(可丢弃->{
msgressponse.setMessageStatus(“错误”);
msgressponse.setErrorMessage(“错误”);
返回msgResponse;
}).join();
}
返回一个新的
CompletableFuture
,当所有给定的CompletableFutures完成时,该新的CompletableFuture将完成。因此,当在中调用join
,然后在apply
中调用时,它会立即返回。本质上,加入是发生在已经完成的期货市场上。这样就消除了阻塞。另外,为了处理可能的异常,应该调用异常的
。您在哪个Java版本上运行此操作?您是否尝试过最新版本的Java 8或Java 10+,正如链接错误中指出的那样?我正在运行Java 8(u201-b09)。最新的Java8是u211。我试试看。还没有试过JDK 10。无论如何,我无法在部署中升级JDK。错误的模糊状态可能表明它是相关的。如果你能可靠地复制它,也许可以提交一份新的记录单。是的,我一直在尝试在没有所有业务逻辑和数据库cal的情况下复制它