CompletableFuture

本文通过一个具体的Java示例介绍了如何使用CompletableFuture来执行异步任务,并展示了带阻塞与不带阻塞的任务执行方式及其结果处理过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class TestCompletableFuture {

    private static final Executor executor = Executors.newFixedThreadPool(4);

    private static void submitSleep(int id) {
        CompletableFuture<String> resultCF = CompletableFuture.supplyAsync(new Supplier<String>() {
            @Override
            public String get() {
                try {
                    // sleep会释放执行权 但不会释放锁 wait会释放执行权和锁
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                }
                return new StringBuffer("success").append(id).toString();
            }
        }, executor);
        // result
        resultCF.thenAccept(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(new StringBuffer(s).append("    :").append(System.currentTimeMillis()).toString());
            }
        });
    }

    private static void submit(int id) {
        CompletableFuture<String> resultCF = CompletableFuture.supplyAsync(new Supplier<String>() {
            @Override
            public String get() {
                return new StringBuffer("success").append(id).toString();
            }
        }, executor);
        // result
        resultCF.thenAccept(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(new StringBuffer(s).append("    :").append(System.currentTimeMillis()).toString());
            }
        });
    }

    public static void main(String args[]) {
        System.out.println("start submit:" + System.currentTimeMillis());
        for (int i=1; i<6; i++) {
            submitSleep(i);
        }
        for (int i=6; i<11; i++) {
            submit(i);
        }
        System.out.println("  end submit:" + System.currentTimeMillis());
    }
}

### CompletableFuture 的用法及错误处理 CompletableFuture 是 Java 8 引入的一个强大工具,用于处理异步编程和复杂的任务链。它不仅支持异步执行任务,还提供了丰富的 API 来处理任务的结果或异常。 #### 基本概念 CompletableFuture 是一个 Future 的增强版本,允许开发者通过回调函数来处理任务完成后的结果或异常[^1]。它支持多种方法来组合多个异步任务,例如 `thenApply`、`thenAccept`、`exceptionally` 等。 #### 创建 CompletableFuture 可以使用以下几种方式创建 CompletableFuture: - 使用 `runAsync` 方法运行不返回结果的任务。 ```java CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { System.out.println("Running in a separate thread: " + Thread.currentThread().getName()); }); future.join(); // Wait for the task to complete ``` - 使用 `supplyAsync` 方法运行返回结果的任务。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { return "Result from supplyAsync"; }); System.out.println(future.join()); // Output the result ``` #### 链式调用 CompletableFuture 支持链式调用来处理任务的结果或异常。例如: - `thenApply`:对前一个任务的结果进行转换。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello") .thenApply(s -> s + " World"); System.out.println(future.join()); // Output: Hello World ``` - `thenAccept`:消费前一个任务的结果。 ```java CompletableFuture.supplyAsync(() -> "Hello World") .thenAccept(System.out::println); ``` - `thenCompose`:将一个 CompletableFuture 的结果作为另一个 CompletableFuture 的输入。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello") .thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " World")); System.out.println(future.join()); // Output: Hello World ``` #### 错误处理 当任务抛出异常时,可以使用 `exceptionally` 或 `handle` 方法来捕获并处理异常。 - `exceptionally`:为任务的异常提供一个默认值。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Task failed"); }).exceptionally(ex -> "Default Value on Exception: " + ex.getMessage()); System.out.println(future.join()); // Output: Default Value on Exception: Task failed ``` - `handle`:为任务的成功或失败提供统一的处理逻辑。 ```java CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Task failed"); }).handle((result, ex) -> { if (ex != null) { return "Handled Exception: " + ex.getMessage(); } return "Result: " + result; }); System.out.println(future.join()); // Output: Handled Exception: Task failed ``` #### 并行任务 可以通过 `allOf` 和 `anyOf` 方法来组合多个 CompletableFuture。 - `allOf`:等待所有任务完成。 ```java CompletableFuture<Void> allFutures = CompletableFuture.allOf( CompletableFuture.runAsync(() -> System.out.println("Task 1")), CompletableFuture.runAsync(() -> System.out.println("Task 2")) ); allFutures.join(); // Wait for both tasks to complete ``` - `anyOf`:等待任意一个任务完成。 ```java CompletableFuture<Object> anyFuture = CompletableFuture.anyOf( CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {} return "Task 1"; }), CompletableFuture.supplyAsync(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {} return "Task 2"; }) ); System.out.println(anyFuture.join()); // Output: Task 2 ``` #### 实际应用 在实际开发中,CompletableFuture 可以用于异步加载数据、并发任务调度等场景。例如,结合数据库查询和缓存操作: ```java CompletableFuture<String> dbFuture = CompletableFuture.supplyAsync(() -> { // Simulate database query try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {} return "Data from DB"; }); CompletableFuture<String> cacheFuture = CompletableFuture.supplyAsync(() -> { // Simulate cache lookup try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {} return "Data from Cache"; }); CompletableFuture<Void> combinedFuture = dbFuture.thenAcceptBoth(cacheFuture, (dbResult, cacheResult) -> { System.out.println("DB Result: " + dbResult); System.out.println("Cache Result: " + cacheResult); }); combinedFuture.join(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值