Java 8 新特性—深入理解 CompletableFuture

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

CompletableFuture 是 Java 8 中引入用于处理异步编程的核心类,它引入了一种基于 Future 的编程模型,允许我们以更加直观的方式执行异步操作,并处理它们的结果或异常。

Future 的局限性

学过 Java 并发或者接触过异步开发的小伙伴应该都知道 Future,通过 Future 我们能够知道异步执行的操作结果,它提供了 isDone() 来检测异步是否已经完成,也可以通过 get() 方法来获取计算结果。在异步计算中,Future 确实是一个非常优秀的接口,但是它依然存在一些局限性:

  1. 缺乏回调机制:Future 没有内置的回调机制,这就意味着我们必须轮询 Future 对象来检查任务是否完成,而不是等待通知。
  2. 无法取消任务:虽然可以通过 cancel() 方法来取消 Future 中的任务,但这并不保证任务会被取消。如果任务已经开始执行,那么 cancel() 方法可能无法终止任务的执行。
  3. 缺乏异常处理机制:Future 通过 get() 方法返回任务的结果或异常,但它无法提供更多的异常处理功能。如果任务抛出异常,你必须在客户端代码中捕获这些异常。
  4. 单一结果:每个 Future 对象只能关联一个任务,这就限制了它的使用,如果我们需要并行执行多个任务并收集它们的结果,我们只能自己管理多个 Future 对象。
  5. 无法进行链式调用:如果我们希望在计算完成后执行特定操作,比如通知用户,这个时候我们就无法使用 Future 来实现了。
  6. 无法组合多任务:在处理多个任务时,Future 并没有提供很好的组合方式,比如我们需要等待 10 任务全部完成后再执行特定操作,这个时候使用 Future 就不是很好操作了。

什么是 CompletableFuture

为了克服 Future 的局限性,Java 8 提供了 CompletableFuture,它构建在 Future 之上,提供了更加强大的异步编程功能,相比 Future 它具备如下优势:

  1. 提供了回调机制:CompletableFuture 提供了回调功能,我们可以注册回调函数来处理任务完成时的结果,而不必阻塞线程等待任务完成。这样可以提高并发性能,减少线程的阻塞时间。
  2. 提供了异常处理:CompletableFutur 具备丰富的异常处理机制,可以捕获任务执行中的异常,并允许我们定义自定义的异常处理策略。
  3. 能够取消任务:我们可以使用 cancel()取消任务的执行,同时还可以指定是否中断正在执行的任务。这提供了更好的任务控制能力。
  4. 强大的异步编程能力:CompletableFuture 提供了丰富的方法来处理异步操作,包括组合转换处理异常以及执行自定义的操作。这使得异步编程更加灵活,可以更轻松地实现复杂的异步任务组合。
  5. 支持组合、链式操作:CompletableFutur 提供了一系列支持组合操作的方法,例如 thenCombine() , thenCompose()thenApplyAsync()等等,使得多个 CompletableFuture 可以轻松组合成一个新的 CompletableFuture,从而更容易构建复杂的异步操作流。

CompletableFuture 提供了比传统 Future 更加强大、更加灵活的异步编程能力,能够更好地满足复杂异步任务处理的需求,能够更加方便地构建复杂的异步操作流,是 Java 8 及以后的版本中,处理异步操作的首选。

CompletableFuture 的核心 API

构建异步操作

CompletableFuture 提供了多种方法用于构建异步操作。

runAsync(): 用于异步执行没有返回值的任务。

它有两个重载方法:

public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)

这两个方法的区别在于:

  • runAsync(Runnable runnable) 会使用 ForkJoinPool 作为它的线程池执行异步代码。
  • runAsync(Runnable runnable, Executor executor) 则是使用指定的线程池执行异步代码。

示例:

    @Test
    public void runAsyncTest(){
        CompletableFuture.runAsync(() ->{
            log.info("死磕 Java 新特性 - 01");
        });

        CompletableFuture.runAsync(() -> {
            log.info("死磕 Java 新特性 - 02");
        }, Executors.newFixedThreadPool(10));
    }

结果

supplyAsync() 用于异步执行有返回值的任务。

supplyAsync() 也有两个重载方法,区别 runAsync() 和一样:

public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值