Java并发编程—CompletableFuture的介绍和使用

article/2025/10/28 7:24:40

        在博主上一篇博客介绍中,Java并发编程—java异步Future的迭代过程_小魏快起床的博客-CSDN博客,这里面给大家分析了Future的使用过程和一些存在的问题,那么针对里面出现的阻塞问题,博主将在这一篇文章给大家介绍清楚

🍏一、认识新的类CompletableFuture

        🍄1、CompletableFuture类在java源代码中的样子:

public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {	}

        🍄2、CompletableFuture类的架构图

        🍄3、再回顾一下博主上一篇博客中讲的FutureTask类结构图:

        🚗 综上:这个新的CompletableFuture类实现了和FutureTask一样的Future类,所以CompletableFuture类里面有FutureTask关于异步任务的这些特性。同时,CompletableFuture还实现了CompletionStage接口,而真正解决之前的阻塞问题的就是咱们CompletionStage接口,而CompletableFuture进行了一个实现,所以就给大家讲解的是CompletableFuture类;

🍏 二、CompletableFuture和CompletionStage源码分别介绍

        🍄 1、接口CompletionStage:

①、CompletionStage代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段。

②、一个阶段的计算执行可以是一个Function,Consumer或者Runnable。

③、一个阶段的执行可能是被单个阶段的完成触发,也可能是由多个阶段一起触发;

        🚗 总结:代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另外一个阶段,类似Linux系统的管道分隔符传参数,说人话就是一阶段完成了,需要做二阶段,这个时候二阶段可能会依靠一阶段的结果来执行一些业务。        

        🍄 2、类CompletableFuture:

        CompletableFuture是对Future的扩展和增强。CompletableFuture实现了Future接口,并在此基础上进行了丰富的扩展,完美弥补了Future的局限性,同时CompletableFuture实现了对任务编排的能力。借助这项能力,可以轻松地组织不同任务的运行顺序、规则以及方式。从某种程度上说,这项能力是它的核心能力。而在以往,虽然通过CountDownLatch等工具类也可以实现任务的编排,但需要复杂的逻辑处理,不仅耗费精力且难以维护。

        🚗 总结:CompletableFuture牛逼就完事儿,FutureTask可以做的这个都可以做,并且还可以做一些Future不能做的事;

🍏 三、CompletableFuture的方法介绍

        介绍一下CompletableFuture里面的方法:

runAsync 创建无返回值的异步任务
supplyAsync 创建有返回值的异步任务

代码案例:

public static void main(String[] args) throws ExecutionException, InterruptedException {// 创建线程池。线程池的"最大池大小"和"核心池大小"都为1(THREADS_SIZE),"线程池"的阻塞队列容量为1(CAPACITY)。ThreadPoolExecutor pool = new ThreadPoolExecutor(1,1,0,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(1));//第一个基本方法runAsyncCompletableFuture<Void> async1 = CompletableFuture.runAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "执行");});//第二个基本方法runAsync,带线程池的CompletableFuture<Void> async2 = CompletableFuture.runAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "执行");}, pool);//第三个基本方法supplyAsyncCompletableFuture<Integer> async3 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "执行");return 11;});System.out.println(async3.get());//第四个基本方法supplyAsyncCompletableFuture<Integer> async4 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "执行");return 12;}, pool);System.out.println(async4.get());//关闭线程池pool.shutdown();}

        🚗 总结:在上面的代码中,每个方法都有2种使用方法,无非就是携带线程池的区别,如果不提供自定义线程池的话,方法内部会用默认的线程池;

         分别执行的效果如下,有数字的是有返回值的,工作中用哪种,取决于实际应用场景:

以上是对这个类和一些方法的初步解析

🍏 四、用CompletableFuompleture做之前的事儿

         之前博主的想法是在主线程中开启一个子线程,然后子线程进行一个计算,然后返回结果值,那么用CompletableFuompleture来做一些试试:

//1、创建一个有返回值的异步任务CompletableFuture<Integer> async = CompletableFuture.supplyAsync(() -> {try {//延迟2sTimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return 11;});System.out.println("主线程正常执行");//获取异步任务的返回值System.out.println(async.get());System.out.println("结束");

效果如下:

        分析:这样执行是没啥问题的,但是还是出现了阻塞的问题,明明都说了换类,都说了这个好用,为啥还会出现阻塞呢,这个显然是我们使用错误了,接下来就给大家演示正确的使用方法

🍏 五、CompletableFuompleture正确的使用方法:

         博主想做这么一件事儿,开启一个异步任务,第一步计算1+2的值,然后将这个值再提供给下一步做+3的操作,然后输出最后的结果,实现一个多线程异步任务编排:

public static void main(String[] args) throws Exception {//1、创建一个线程池ThreadPoolExecutor pool = new ThreadPoolExecutor(1,1,0,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(1));//2、创建异步编排任务CompletableFuture.supplyAsync(() -> {//延迟2stry { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { }//做一下加法然后返回结果return 1 + 2;}, pool).thenApply(e -> {//根据上一步的结果+3return e + 3;}).whenComplete((v, f) -> {//判断是否有异常,如果没有就输出结果值if (f == null) {System.out.println("结果值:" + v);}}).exceptionally(e -> {//异常输出,whenComplete里面的f不为null时触发e.printStackTrace();return null;});//3、主线程执行输出System.out.println("输出main线程");//4、关闭线程池pool.shutdown();}

效果如下:

        🚗 总结:在这个案例中,没有用get()方式,用了一些CompletableFuture类里面的自带方法,这就是真正实现了一个异步任务编码的实现,博主这里只用了很简单的例子,铁子们在工作中,完全可以用这种方式来提高效率,这个可以用在数据统计中;

🍏 六、常用方法介绍

         在上面的案例中用到了一些方法,在这里可以做一个介绍:      

🍄 1、thenApply / thenApplyAsync 异步回调

前者是由执行job1的线程立即执行job2,即两个job都是同一个线程执行的
后者是将job2提交到线程池中异步执行,实际执行job2的线程可能是另外一个线程

🍄 2、exceptionally whenComplete handle

whenComplete 未发生异常正常返回值发生异常就返回异常,一般配合exceptionally使用
exceptionally确认会发生异常
handle 基本一致 区别在于 handle 有返回值

🍄 3、thenAccept / thenRun

thenAccept 同 thenApply 接收上一个任务的返回值作为参数,但是无返回值;
thenRun 的方法没有入参,也没有返回值

🍕:博主写博客主要是分享技术,分享技术的一个迭代过程,分享技术中发生的问题如何进行解决,欢迎各位铁子留言讨论;


http://chatgpt.dhexx.cn/article/wYUFYGhr.shtml

相关文章

Java8 CompletableFuture runAsync等使用学习总结 submit() execute()等

一般的 Executors 的 execute以及submit 并发包下 Executors 创建的线程存在 一个 execute()&#xff0c;以及三个 submit() 不同的是使用 execute() 执行的任务是没有返回值的&#xff0c;使用 submit() 则是存在返回值的&#xff0c;这与接下里要说的 CompletableFuture.run…

实现异步编程,这个工具类你得掌握!

前言 最近看公司代码&#xff0c;多线程编程用的比较多&#xff0c;其中有对CompletableFuture的使用&#xff0c;所以想写篇文章总结下 在日常的Java8项目开发中&#xff0c;CompletableFuture是很强大的并行开发工具&#xff0c;其语法贴近java8的语法风格&#xff0c;与st…

Java异步编程之CompletableFuture

异步任务 Future获取异步任务结果 利用 Java 并发包提供的 Future 可以很容易获得异步任务的执行结果&#xff0c;无论异步任务是通过线程池 ThreadPoolExecutor 执行的&#xff0c;还是通过手工创建子线程来执行的。利用多线程可以快速将一些串行的任务并行化&#xff0c;从而…

JUC异步编程

什么是JUC JUC的意思是java并发编程工具包&#xff0c;是java.util.concurrent包的简称。目的就是为了更好的支持高并发任务&#xff0c;让开发者利用这个包进行的多线程开发时&#xff0c;可以有效的减少竞争条件和死锁线程。 异步编程 模拟用户下单操作。。。 1、根据地址…

线程、多线程的使用、线程池、异步(CompletableFuture)-48

一&#xff1a;线程 1.初始化线程的四种方式 1&#xff09;、继承 Thread public class ThreadTest {public static void main(String[] args) {System.out.println("main...start...");Thread01 thread new Thread01();//启动线程thread.start();System.out.pri…

CompletableFuture 执行异步任务

CompletableFuture 执行异步任务 参考&#xff1a; (10条消息) Java 8 的异步编程利器 CompletableFuture 真香&#xff01;_不才陈某的博客-CSDN博客 提供几十种方法&#xff0c;帮助异步任务执行调用&#xff1b; 主要包括&#xff1a; 创建异步任务任务异步回调多个任务…

CompletableFuture实现异步编排全面分析和总结

一、&#x1f308;CompletableFuture简介 CompletableFuture结合了Future的优点&#xff0c;提供了非常强大的Future的扩展功能&#xff0c;可以帮助我们简化异步编程的复杂性&#xff0c;提供了函数式编程的能力&#xff0c;可以通过回调的方式处理计算结果&#xff0c;并且提…

【Java8新特性--->异步处理】CompletableFuture

一、引入 假设一个商品详情页需要以下操作&#xff1a; 查询展示商品的基本信息耗时&#xff1a;0.5s查询展示商品的销售信息耗时&#xff1a;0.7s查询展示商品的图片信息耗时&#xff1a;1s查询展示商品销售属性耗时&#xff1a;0.3s查询展示商品规格属性耗时&#xff1a;1.…

CompletableFuture API

目录 1. 为什么要用CompletableFuture1.1 API 2. CompletableFuture Demo1. 创建CompletableFuture2. 定义CompletableFuture完成时和异常时需要回调的实例3. CompletableFuture的优点 3. demo&#xff1a;多个CompletableFuture串行执行4. demo&#xff1a;多个CompletableFut…

CompletableFuture实战与分析

Future对于结果的获取不够好&#xff0c;只能通过阻塞或者轮询的方式得到任务的结果。在Java8中Doug Lea大师提供了一个CompletableFuture工具类&#xff0c;可以更优雅的对异步并行操作进行编排。 Future VS CompletableFuture CompletableFuture支持手动完成任务&#xff0…

Java8 CompletableFuture异步非阻塞做法

创建异步任务 Future.submit supplyAsync / runAsync 异步回调 thenApply / thenApplyAsync thenAccept / thenRun exceptionally whenComplete handle 组合处理 thenCombine / thenAcceptBoth / runAfterBoth applyToEither / acceptEither / runAfterEither thenCom…

2022.2.5 第十三次周报

文章目录 前言一、论文阅读《ROCKET: Exceptionally fast and accurate time series classification using random convolutional kernels》Abstract摘要Introduction介绍Method方法Kernels内核Transform转换Classifier分类器Complexity Analysis复杂性分析 Experiments实验Con…

并发编程(十五)-CompletableFuture中常用方法的使用与分析

文章目录 一、CompletableFuture API介绍1. 描述2. CompletionStage3. CompletableFuture 4个核心静态方法&#xff08;1&#xff09;runAsync(Runnable runnable)&#xff08;2&#xff09;runAsync(Runnable runnable, Executor executor)&#xff08;3&#xff09;supplyAsy…

Java 编程问题:十一、并发-深入探索

原文&#xff1a;Java Coding Problems 协议&#xff1a;CC BY-NC-SA 4.0 贡献者&#xff1a;飞龙 本文来自【ApacheCN Java 译文集】&#xff0c;自豪地采用谷歌翻译。 本章包括涉及 Java 并发的 13 个问题&#xff0c;涉及 Fork/Join 框架、CompletableFuture、ReentrantLock…

线程(十二)---CompletableFuture(三)

写在前面&#xff1a;各位看到此博客的小伙伴&#xff0c;如有不对的地方请及时通过私信我或者评论此博客的方式指出&#xff0c;以免误人子弟。多谢&#xff01; 示例五&#xff1a;异常处理 接着上一篇记录一下CompletableFuture的异常处理&#xff0c;异常处理通常使用…

dice loss

Dice Loss 最先是在VNet 这篇文章中被提出&#xff0c;后来被广泛的应用在了医学影像分割之中。 Dice 系数 Dice系数作为损失函数的原因和混淆矩阵有着很大的关系&#xff0c;下图给出的是一个混淆矩阵&#xff1a; 其中的一些关键指标如下&#xff1a; 精确率(precision)表…

Hinge loss

声明&#xff1a; 参考自维基百科后面可能会更新 Hinge Loss 在机器学习中&#xff0c;hinge loss作为一个损失函数(loss function)&#xff0c;通常被用于最大间隔算法(maximum-margin)&#xff0c;而最大间隔算法又是SVM(支持向量机support vector machines)用到的重要算法…

【深度学习】一文读懂机器学习常用损失函数(Loss Function)

【深度学习】一文读懂机器学习常用损失函数&#xff08;Loss Function&#xff09; 最近太忙已经好久没有写博客了&#xff0c;今天整理分享一篇关于损失函数的文章吧&#xff0c;以前对损失函数的理解不够深入&#xff0c;没有真正理解每个损失函数的特点以及应用范围&#x…

Pytorch之loss(损失函数)

损失函数也在torch.nn下&#xff0c;具体可以参考文档&#xff0c;也可以参考官网 先根据L1Loss举例 我个人感觉这里的描述还是到官网的文档找比较好&#xff0c;公式看的比文档清楚 import torch from torch import nninputs torch.tensor([[3, 2, 1],[1, 2, 3]], dtypetorch…

机器学习 损失函数 Loss function

损失函数 最小二乘法极大似然估计法交叉熵 【本文根据B站-王木头学科学-视频所学】 在梯度下降中&#xff0c;所求的梯度其实就是损失函数的梯度。 损失函数有三种设计方法&#xff1a; &#xff08;1&#xff09;最小二乘法 &#xff08;2&#xff09;极大似然估计法 &#x…