简体   繁体   中英

CompletableFuture: after async call, process result in current thread

I am trying to understand the CompletableFuture interface in Java 8. My current code is:

CompletableFuture.supplyAsync(() -> wachtwoordBijwerken(gebruikersnaam, wachtwoord))
    .thenAccept(this::saveOrUpdateGebruiker)
    .exceptionally(e ->
    {
        log.error("Fout bij het bijwerken van wachtwoord voor gebruiker: " + gebruikersnaam, e);
        return null;
    });

I expected the call saveOrUpdateGebruiker() to run in the main thread after the async call in the newly created thread is completed. However, the call is still in another thread, which causes problems in the underlying hibernate implementation.

Is there a way to use CompletableFuture for a non blocking async call, and still being able to use the result in my current thread?

Not automatically no. When performing operations as provided by CompletableFuture with supplyAsync , thenAccept etc. they're all performed by a thread in the threadpool. That allows you to do "fire and forget" operations and continuing work in the main thread as you see fit.

If you want to perform work in your current thread after the CompletableFuture has finished, you need to wait and check for its completion by using isDone() and/or get() methods.

However if you do this, then there is no advantage of using CompletableFuture over a normal Future (eg FutureTask ).

Using CompletableFuture is an overkill for your scenario. CompletableFuture is non-blocking in its design and when the job is done, you can collect its results by using join() or polling isDone() method and then do synchronous operation. If you have only one process keep sending tasks to dedicated ThreadPool, there's no advantage of using CompletableFuture than CompletionService or just ExecutorService . I wrote a simple blog on one scenario where CompletableFuture is a good fit compared to traditional Threadpool: https://medium.com/@zhongzhongzhong/beauty-of-completablefuture-and-where-should-you-use-it-6ac65b7bfbe

You can use the method thenAcceptAsync(Runnable, Executor) which uses the executor you passed in parameter to execute the callback, which it can be eventually the same that the one you have for the caller

Like that, you can control the thread/executor used for executing your callback code

See also : This related Stackoverflow question

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM