简体   繁体   中英

is `CompletableFuture.completedFuture … thenAccept` equivalent to sequential processing?

I'm working on a project with a lot of CompletableFuture.completedFuture... thenAccept codes, eg

    public CompletableFuture<Boolean> callee() {
        boolean result = ... // Do something and get result - Step A
        return CompletableFuture.completedFuture(Boolean.valueOf(result));
    }

    public void caller() {
        callee().thenAccept(result -> {
            // Detect if call success or failure - Step B
            new Throwable().printStackTrace(); // the debug code: stacktrace shows it is called from caller
        });
    }

I concluded that Step A and Step B are called sequentially in one thread.

So can I simplify it like this?

    public boolean callee() {
        boolean result = ... // Do something and get result
        return result;
    }

    public void caller() {
        boolean result = callee();
        // Detect if call success or failure
    }

Yes , you can simplify it like this. The long version:

I think the question should be rather: "Is this usage of CompletableFuture appropriate?". No, it's not. This code is using CompletableFuture like a wrapper, a package, to pass data around and not as a tool to execute code asynchronously. This tool can be used to pass data around between threads, but it's not what this code is doing.

Calling CompletableFuture.completedFuture does nothing but create a new CompletableFuture that is completed with whatever you pass to the method. Then you call thenAccept on it, which has basically the following effect: "Take the result when it's done and let the thread that has calculated the result execute the following code. If the result is already calculated, let the caller execute the following code themself." The "following code" is simply the lambda you pass to thenAccept .

The initial CompletableFuture is completed instantly and the following code gets executed by the thread that calls thenAccept directly. The thread that executes caller and callee does everything itself. So this part is effectively doing nothing asynchronously. Therefore, the code is equivalent to the simpler code in the second example without CompletableFuture .

To actually make use of CompletableFuture , you should run boolean result =... // Do something and get result - Step A asynchronously by eg creating this initial future using CompletableFuture.supplyAsync . The chained code will also be run asynchronously.

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