java - 以递归方式使用 java 8 CompletableFuture
问题描述
我需要从数据库加载记录,然后在链中对它们执行一些操作,我想重构我们现有的代码以利用 CompletableFuture API
基本思想是
- a. 将记录加载到队列中 b. 对于队列中的每个记录,请执行以下操作:
- 执行任务 A(需要一段时间)
- 基于任务 A 执行任务 B(需要更多时间)
- 执行任务 C(也需要时间)
一些记录当然比其他记录结束得更快,所以我希望一旦完成,另一个(来自队列)将开始执行
我有以下代码
gamesQueue = new PriorityQueue<Game>();
completable = new LinkedList<CompletableFuture<String>>();
Instant start = Instant.now();
Executor pool = Executors.newCachedThreadPool();
DB.getInstance().getConn().useHandle(handle -> {
handle.attach(GameService.class).list().stream().forEach(game -> gamesQueue.add(game));
});
这将加载我的记录然后我执行以下操作
while (!gamesQueue.isEmpty()) {
CompletableFuture<String> step1 = CompletableFuture.supplyAsync(this::getCurrentGame, pool)
.thenApply(CapitalLetterTask::capitalize).thenApply(game-> {
if(game.isEndedExceptionaly()) {
handleNumber5Exception(game);
throw new CompletionException(new NumberFiveException(game, "got number 5"));
}
return game;
})
.thenApply(AddStarTask::addStarToGame).exceptionally(ExceptionHandler::handleWeirdEx);
completable.add(step1);
}
while (!completable.isEmpty()) {
CompletableFuture<String> completed = completable.poll();
if (completed.isDone()) {
try {
log.debug("result: {}", completed.get());
} catch (Exception ex) {
}
} else if(completed.isCompletedExceptionally()) {
try{ //never enters here
log.debug("This is a bad result:{} ", completed.get());
}catch(Exception ex) {
}
}
else {
completable.add(completed);
}
}
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
log.debug("Total time: {}", duration.getSeconds());
loadGames(); <-- call itself
}
我不满足于我的异常处理此外我看到即使是应该在第一阶段被捕获的期货仍在进一步传递
我想问的是如何以这样的方式实现它,即每个方法都可以抛出自己的自定义异常,被捕获和处理,而无需将其进一步向下传递
解决方案
推荐阅读
- html - 如何设置
- php - 在 Laravel 中调用未定义的函数 App\Http\Controllers\categories()
- c# - 如何使用 Microsoft Graph sdk 通过电子邮件地址从 Active Directory 获取用户信息
- css - 如何选择包含 str 的类的所有元素?
- r - 有没有办法解决R中的方程?
- javascript - 有没有办法遍历数组中的对象?
- azure-data-factory - 如何在数据流中加入数据
- ssh - 设置从 Linux 到 Windows 10 的无密码 SSH
- java - 如何处理 xml 标签中的下划线
- node.js - 使用 node.js 在 aws lambda 上调整图像大小的sharp或gm的更好替代品