Posted in

CompletableFuture join() vs get() 指南_AI阅读总结 — 包阅AI

包阅导读总结

1. `CompletableFuture`、`join()`、`get()`、`异步编程`、`异常处理`

2. 本文介绍了 Java 中 CompletableFuture 的 join()和 get()方法用于等待异步任务完成并获取结果,比较了它们在异常处理、使用场景和阻塞行为上的差异,并通过代码示例展示了用法和输出,最后总结选择取决于具体情况。

3.

– 概述 CompletableFuture

– 是 Java 8 引入的用于异步编程的工具

– 属于 java.util.concurrent 包

– 可创建、组合和灵活执行异步任务

– 介绍 join()和 get()方法

– join():等待异步任务完成,不抛出检查异常,异常时包装在 UncheckedExecutionException 中重新抛出

– get():等待并获取结果,抛出检查异常 InterruptedException 和 ExecutionException

– 比较 join()和 get()

– 异常处理不同

– 使用场景不同

– 阻塞行为相同

– 代码示例及解释

– 展示了使用 join()和 get()获取异步任务结果

– 说明了正常情况和异常情况的输出

– 结论

– 选择 join()或 get()取决于具体用例和异常处理方式

思维导图:

文章地址:https://www.javacodegeeks.com/guide-to-completablefuture-join-vs-get.html

文章来源:javacodegeeks.com

作者:Yatin Batra

发布时间:2024/8/5 12:21

语言:英文

总字数:782字

预计阅读时间:4分钟

评分:80分

标签:Java,CompletableFuture,异步编程,并发,异常处理


以下为原文内容

本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com

Java’s CompletableFuture is a powerful tool for asynchronous programming, offering various methods to handle and manipulate future tasks. Among these methods, join() and get() are two commonly used for waiting for the completion of a task and retrieving its result. Let us delve into understanding the key differences between CompletableFuture join vs get.

1. Overview of CompletableFuture

CompletableFuture is a part of Java’s java.util.concurrent package, introduced in Java 8. A CompletableFuture is a versatile tool in Java’s concurrency API that allows you to write non-blocking, asynchronous code. It provides methods to create, combine, and flexibly execute asynchronous tasks. By using CompletableFuture, you can handle long-running computations without blocking the main thread, thus improving the performance and responsiveness of your application.

1.1 The join() Method

The join() method is a part of the CompletableFuture class and is used to wait for the completion of the asynchronous task. Unlike get(), join() does not throw a checked exception.

public T join()

The method waits if necessary for the computation to complete and then retrieves its result. If the computation completes exceptionally, join() wraps the exception in an UncheckedExecutionException and rethrows it.

1.2 The get() Method

The get() method, also part of the CompletableFuture class, is used to retrieve the result of the computation, blocking if necessary until the computation is complete.

public T get() throws InterruptedException, ExecutionException

This method waits if necessary for the computation to complete and then retrieves its result. If the computation completes exceptionally, get() throws the checked exceptions InterruptedException or ExecutionException.

2. Comparison: join() vs. get()

While both join() and get() serve to wait for a CompletableFuture to complete and retrieve its result, there are key differences:

  • Exception Handling: join() throws an unchecked exception (CompletionException), while get() throws checked exceptions (InterruptedException and ExecutionException).
  • Usage Scenario: Use join() when you want to avoid handling checked exceptions, typically in a lambda or method reference context. Use get() when you need to handle interruptions and other execution exceptions explicitly.
  • Blocking Behavior: Both methods block the calling thread until the computation is complete.

3. Code Example and Breakdown

Here is an example demonstrating the use of join() and get():

import java.util.concurrent.CompletableFuture;import java.util.concurrent.ExecutionException;public class CompletableFutureExample {    public static void main(String[] args) {        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {            try {                Thread.sleep(2000);            } catch (InterruptedException e) {                throw new IllegalStateException(e);            }            return "Hello, World!";        });        // Using join()        String resultJoin = future.join();        System.out.println("Result using join: " + resultJoin);        // Using get()        try {            String resultGet = future.get();            System.out.println("Result using get: " + resultGet);        } catch (InterruptedException | ExecutionException e) {            e.printStackTrace();        }    }}

In this example, a CompletableFuture is created to run a task asynchronously. The task simulates a delay using Thread.sleep(). The result is then retrieved using both join() and get() methods, demonstrating their usage and behavior.

3.1 Code Output and Explanation

Here is the output of the provided code example:

Result using join: Hello, World!Result using get: Hello, World!

3.1.1 Explanation

  • Asynchronous Task:
    • The code creates a CompletableFuture using supplyAsync(), which runs a task asynchronously.
    • This task simulates a delay of 2 seconds using Thread.sleep(2000), then returns the string “Hello, World!”.
  • Using join():
    • future.join() is called, which waits for the asynchronous task to complete.
    • Once the task is complete, join() returns the result, “Hello, World!”, and prints it.
  • Using get():
    • future.get() is called, which also waits for the asynchronous task to complete.
    • Similar to join(), get() returns the result, “Hello, World!”, and prints it.
    • If the task were interrupted or failed, get() would throw InterruptedException or ExecutionException, respectively. However, in this case, the task was completed successfully.

3.2 Output When an Exception Occurs

Now let’s say if we modify the code to throw the exception within the asynchronous task, both join() and get() will handle it differently:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {    throw new RuntimeException("Task failed");});

3.2.1 Output Using join()

The join() method will throw an unchecked CompletionException, which wraps up the original exception.

Exception in thread "main" java.util.concurrent.CompletionException: java.lang.RuntimeException: Task failed    at java.base/java.util.concurrent.CompletableFuture.join(CompletableFuture.java:2046)    at CompletableFutureExample.main(CompletableFutureExample.java:10)Caused by: java.lang.RuntimeException: Task failed    at CompletableFutureExample.lambda$main$0(CompletableFutureExample.java:7)    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)    ... 1 more

3.2.2 Output Using get()

The get() method will throw ExecutionException, which wraps up the original exception.

Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.RuntimeException: Task failed    at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:389)    at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2001)    at CompletableFutureExample.main(CompletableFutureExample.java:15)Caused by: java.lang.RuntimeException: Task failed    at CompletableFutureExample.lambda$main$0(CompletableFutureExample.java:7)    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)    ... 1 more

4. Conclusion

Both join() and get() methods of CompletableFuture provide mechanisms to wait for the completion of an asynchronous task and retrieve its result. The choice between them depends on your specific use case and how you prefer to handle exceptions. Understanding these differences helps you write more robust and maintainable asynchronous code in Java.