CompletableFuture:异步调用后,处理当前线程的结果

时间:2017-07-03 13:46:02

标签: java multithreading hibernate asynchronous

我试图理解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进行非阻塞异步调用,并且仍能在当前线程中使用结果?

3 个答案:

答案 0 :(得分:3)

不是自动否。执行CompletableFuturesupplyAsyncthenAccept等提供的操作时,它们全部由线程池中的线程执行。这样你就可以“开火”并“忘记”。您认为合适的主线程中的操作和继续工作。

如果您想在CompletableFuture完成后在当前线程中执行工作,则需要等待并使用isDone()和/或get()方法检查其完成情况。< / p>

但是,如果您这样做,那么使用CompletableFuture优于普通Future(例如FutureTask)是没有优势的。

答案 1 :(得分:1)

使用CompletableFuture对您的方案来说太过分了。 CompletableFuture在设计中是非阻塞的,当作业完成后,您可以使用join()或轮询isDone()方法收集其结果,然后执行同步操作。如果您只有一个流程继续将任务发送到专用的ThreadPool,那么使用CompletableFuture比CompletionServiceExecutorService没有优势。我在一个场景上写了一个简单的博客,与传统的Threadpool相比,CompletableFuture非常适合:https://medium.com/@zhongzhongzhong/beauty-of-completablefuture-and-where-should-you-use-it-6ac65b7bfbe

答案 2 :(得分:0)

您可以使用方法thenAcceptAsync(Runnable, Executor)使用您在参数中传递的执行程序来执行回调,它最终可以与您为调用者所拥有的回调相同

与此类似,您可以控制用于执行回调代码的线程/执行程序

另请参阅:This related Stackoverflow question