CompletableFuture
2025-4-20
| 2025-4-20
Words 1652Read Time 5 min
type
status
date
slug
summary
tags
category
icon
password

为什么要有CompletableFuture

future 接口定义了操作异步任务执行的一些方法,如获取异步任务的执行结果,取消任务执行,判断任务是否被取消,判断任务执行是否完毕等。
notion image
image-20230625103629264
它可以为主线程开一个分支任务,一般使用他的实现类 FutureTask 异步任务。
异步多线程任务执行且返回有结果,有三个特点:多线程/有返回/异步任务
可以实现 runnable 接口和 Callable 接口,但是 runnable接口不支持返回值,callable 接口虽然有返回值,异步执行的时候不能中断等各种操作。
而 FutureTask 满足所有
结果
notion image
image-20230625112154628

优缺点

上面是 Future 的实现类 FutureTask,看起来还可以,那为什么要演化为 CompletableFuture,Future有什么不足,CompletableFuture又进行了什么改进?
  • 优点:Future+线程池异步多线程任务配合,能显著提高程序的运行效率。
  • 缺点:
    • get()阻塞—一旦调用get()方法求结果,一旦调用不见不散,非要等到结果才会离开,不管你是否计算完成,如果没有计算完成容易程序堵塞。
    • isDone()轮询—轮询的方式会耗费无谓的cpu资源,而且也不见得能及时得到计算结果,如果想要异步获取结果,通常会以轮询的方式去获取结果,尽量不要阻塞。
  • 结论:Future对于结果的获取不是很友好,只能通过阻塞或轮询的方式得到任务的结果。

代码实现

通过轮询的方式获取任务结果,不让程序阻塞。
这种轮询的方式也只是把等待信息打印出来了,实际上还是在阻塞。

完成一些复杂的任务

  • 对于简单的业务场景使用Future完全ok
  • 回调通知:
    • 应对Future的完成时间,完成了可以告诉我,也就是我们的回调通知
    • 通过轮询的方式去判断任务是否完成这样非常占cpu并且代码也不优雅
  • 创建异步任务:Future+线程池组合
  • 多个任务前后依赖可以组合处理(水煮鱼—>买鱼—>调料—>下锅):
    • 想将多个异步任务的结果组合起来,后一个异步任务的计算结果需要钱一个异步任务的值
    • 想将两个或多个异步计算合并成为一个异步计算,这几个异步计算互相独立,同时后面这个又依赖前一个处理的结果
  • 对计算速度选最快的:
    • 当Future集合中某个任务最快结束时,返回结果,返回第一名处理结果
  • 结论
    • 使用Future之前提供的那点API就囊中羞涩,处理起来不够优雅,这时候还是让CompletableFuture以声明式的方式优雅的处理这些需求。
    • 从i到i++
    • Future能干的,CompletableFuture都能干

    CompletableFuture对Future的改进

    CompletableFuture为什么会出现

    get()方法在Future计算完成之前会一直处在阻塞状态下,阻塞的方式和异步编程的设计理念相违背。
    • isDene()方法容易耗费cpu资源(cpu空转),
    • 对于真正的异步处理我们希望是可以通过传入回调函数,在Future结束时自动调用该回调函数,这样,我们就不用等待结果
    jdk8设计出CompletableFuture,CompletableFuture提供了一种观察者模式类似的机制,可以让任务执行完成后通知监听的一方。
    get()方法会在 future 计算完成之前会一直处在阻塞状态下,CompletableFuture使用了回调的方法进行获取结果,当运行完成之后主动通知计算结果。

    CompletableFuture和CompletionStage介绍

    类架构说明
    notion image
    img
    • 接口CompletionStage
      • 代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段。
      • 一个阶段的执行可能是被单个阶段的完成触发,也可能是由多个阶段一起触发
    • 类CompletableFuture
      • 提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果,也提供了转换和组合CompletableFuture的方法
      • 它可能代表一个明确完成的Future,也可能代表一个完成阶段(CompletionStage),它支持在计算完成以后触发一些函数或执行某些动作

    实现 CompletableFuture

    runAsync 无返回值

    CompletableFuture优点:

    • 异步任务结束时,会自动回调某个对象的方法
    • 主线程设置好回调后,不用关心异步任务的执行,异步任务之间可以顺序执行
    • 异步任务出错时,会自动回调某个对象的方法
    Docker背景-理论centos安装docker
    Loading...