JUC高并发编程12:CompletableFuture异步回调

12 篇文章 0 订阅

1 CompletableFuture 简介

CompletableFuture 是 Java 8 引入的一个强大的异步编程工具,它实现了 FutureCompletionStage 接口。Future 接口用于表示一个异步任务的引用,而 CompletionStage 接口则定义了多种异步方法,使得 CompletableFuture 能够支持复杂的异步任务链和回调机制。

1.1 CompletableFuture 的特点

  • 非阻塞CompletableFuture 允许任务在主线程之外的线程中运行,并通过回调机制在主线程中获取任务的执行状态、是否完成、是否异常等信息。
  • 灵活的回调机制:支持多种回调方法,如 thenApplythenAcceptthenRun 等,可以在任务完成后执行额外的操作。
  • 链式调用:支持将多个异步任务串联起来,形成一个链式的 pipeline 调用。
  • 合并多个 Future:支持将多个 CompletableFuture 合并,并在所有任务完成后执行某些操作。
  • 异常处理:提供了异常处理的 API,可以更好地定位和处理异步任务中的异常。

2 Future 与 CompletableFuture

2.1 Future 的缺点

  1. 不支持手动完成:无法手动通知正在执行的线程任务结果,必须主动取消或一直等待任务完成。
  2. 不支持进一步的非阻塞调用:通过 Future.get() 方法会一直阻塞直到任务完成,无法在获取任务结果后执行额外的任务。
  3. 不支持链式调用:无法将一个 Future 的结果传递给下一个 Future 进行处理。
  4. 不支持多个 Future 合并:无法在多个 Future 并行执行完毕后执行某些操作。
  5. 不支持异常处理Future 的 API 没有任何异常处理的机制,难以定位和处理异步任务中的异常。

2.2 CompletableFuture 的优势

  1. 手动完成:可以通过 complete 方法手动完成任务,并通知等待的线程。
  2. 非阻塞调用:支持多种回调方法,如 thenApplythenAcceptthenRun 等,可以在任务完成后执行额外的操作。
  3. 链式调用:支持将多个异步任务串联起来,形成一个链式的 pipeline 调用。
  4. 合并多个 Future:支持将多个 CompletableFuture 合并,并在所有任务完成后执行某些操作。
  5. 异常处理:提供了异常处理的 API,如 exceptionallyhandle 等,可以更好地定位和处理异步任务中的异常。

3 CompletableFuture 的基本用法

3.1 创建 CompletableFuture

CompletableFuture<String> future = new CompletableFuture<>();

3.2 手动完成任务

future.complete("Task completed");

3.3 异步执行任务

  • 没有返回值的异步任务:使用 CompletableFuture.runAsync()
  • 有返回值的异步任务:使用 CompletableFuture.supplyAsync()
// 没有返回值的异步任务
CompletableFuture<Void> runAsyncFuture = CompletableFuture.runAsync(() -> {
    System.out.println("Running async task");
});

// 有返回值的异步任务
CompletableFuture<String> supplyAsyncFuture = CompletableFuture.supplyAsync(() -> {
    return "Task result";
});

3.4 回调方法

  • 线程依赖:当一个线程依赖另一个线程时,可以使用 thenApply 方法来把这两个线程串行化。
  • 消费处理结果thenAccept 消费处理结果,接收任务的处理结果,并消费处理,无返回结果。
// 线程依赖
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Task result");
future.thenApply(result -> {
    return result.toUpperCase();
}).thenAccept(result -> {
    System.out.println("Processed result: " + result);
});

3.5 异常处理

  • exceptionally:异常处理,出现异常时触发。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    if (true) {
        throw new RuntimeException("Exception occurred");
    }
    return "Task result";
});

future.exceptionally(ex -> {
    System.out.println("Exception occurred: " + ex.getMessage());
    return "Default value";
}).thenAccept(result -> {
    System.out.println("Final result: " + result);
});

3.6 合并多个 Future

  • thenCompose:合并两个有依赖关系的 CompletableFuture 的执行结果。
  • allOf:一系列独立的 CompletableFuture 任务,等其所有的任务执行完后做一些事情。
  • anyOf:只要在多个 CompletableFuture 里面有一个返回,整个任务就可以结束,而不需要等到每一个 CompletableFuture 结束。
// thenCompose
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Result 1");
CompletableFuture<String> future2 = future1.thenCompose(result ->
    CompletableFuture.supplyAsync(() -> result + " Result 2")
);

// allOf
CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> "Result A");
CompletableFuture<String> futureB = CompletableFuture.supplyAsync(() -> "Result B");
CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(futureA, futureB);

allOfFuture.thenRun(() -> {
    System.out.println("All tasks completed");
});

// anyOf
CompletableFuture<String> futureX = CompletableFuture.supplyAsync(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return "Result X";
});
CompletableFuture<String> futureY = CompletableFuture.supplyAsync(() -> "Result Y");
CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(futureX, futureY);

anyOfFuture.thenAccept(result -> {
    System.out.println("First completed task result: " + result);
});

4 案例

public class CompletableFutureDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 异步调用 没有返回值
        CompletableFuture<Void> completableFuture1 = CompletableFuture.runAsync(()->{
            System.out.println(Thread.currentThread().getName()+" completableFuture1");
        });
        completableFuture1.get();
        // 异步调用 有返回值
        CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(()->{
            System.out.println(Thread.currentThread().getName()+" completableFuture2");
            // 模拟异常
            int i = 1/0;
            return 1024;
        });
        completableFuture2.whenComplete((t,u)->{
            System.out.println("----t=" + t);
            System.out.println("----u=" + u);
        }).get();
    }
}

5 思维导图

在这里插入图片描述

6 参考链接

【尚硅谷】大厂必备技术之JUC并发编程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值