我试图理解Java 8中的CompletableFuture接口。 我目前的代码是:
CompletableFuture.supplyAsync(() -> wachtwoordBijwerken(gebruikersnaam, wachtwoord))
.thenAccept(this::saveOrUpdateGebruiker)
.exceptionally(e ->
{
log.error("Fout bij het bijwerken van wachtwoord voor gebruiker: " + gebruikersnaam, e);
return null;
});
我希望在新创建的线程中的异步调用完成后,调用saveOrUpdateGebruiker()
在主线程中运行。
但是,调用仍然在另一个线程中,这会导致底层hibernate实现出现问题。
有没有办法使用CompletableFuture
进行非阻塞异步调用,并且仍能在当前线程中使用结果?
答案 0 :(得分:3)
不是自动否。执行CompletableFuture
与supplyAsync
,thenAccept
等提供的操作时,它们全部由线程池中的线程执行。这样你就可以“开火”并“忘记”。您认为合适的主线程中的操作和继续工作。
如果您想在CompletableFuture
完成后在当前线程中执行工作,则需要等待并使用isDone()
和/或get()
方法检查其完成情况。< / p>
但是,如果您这样做,那么使用CompletableFuture
优于普通Future
(例如FutureTask
)是没有优势的。
答案 1 :(得分:1)
使用CompletableFuture对您的方案来说太过分了。 CompletableFuture在设计中是非阻塞的,当作业完成后,您可以使用join()或轮询isDone()方法收集其结果,然后执行同步操作。如果您只有一个流程继续将任务发送到专用的ThreadPool,那么使用CompletableFuture比CompletionService或ExecutorService没有优势。我在一个场景上写了一个简单的博客,与传统的Threadpool相比,CompletableFuture非常适合:https://medium.com/@zhongzhongzhong/beauty-of-completablefuture-and-where-should-you-use-it-6ac65b7bfbe
答案 2 :(得分:0)
您可以使用方法thenAcceptAsync(Runnable, Executor)使用您在参数中传递的执行程序来执行回调,它最终可以与您为调用者所拥有的回调相同
与此类似,您可以控制用于执行回调代码的线程/执行程序