回顾CompletableFuture 异步编排

CompletableFuture任务编排案例 场景 一个接口内有很多的业务逻辑,这些业务逻辑有的是可以并行执行的,有的是有先后顺序的。为了保证异步执行提升效率,并且异步中又有先后逻辑顺序,可以使用CompletableFuture异步编排的类。 异步编排任务的创建及基本使用 /** * 1:异步编排任务的创建及基本使用 * 使用线程池,异步执行任务。并且可以获取到任务的返回值。并且对任务的结果进行二次加工。 */ public class CompletableFutureTest { public static ThreadPoo 阅读详情

一 概述

        在 Java 8 中, 新增加了一个包含 50 个方法左右的类: CompletableFuture,提供了非常强大的 Future 的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提供了转换和组合 CompletableFuture 的方法CompletableFuture 类实现了 Future 接口,所以你还是可以像以前一样通过`get`方法阻塞或 者轮询的方式获得结果,但是这种方式不推荐使用。 CompletableFuture 和 FutureTask 同属于 Future 接口的实现类,都可以获取线程的执行结果。

        

二 代码实践

   //自定义异步线程池,并且不存在返回值
        CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName());
        }, executor);

        //使用JDK默认的线程池,并且不存在返回值
        CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName());
        });

        //自定义异步线程池,并且存在返回值
        CompletableFuture<Integer> futureE = CompletableFuture.supplyAsync(() -> 1, executor);
        System.out.println(Thread.currentThread().getName() + "futureE.get() = " + futureE.get());

        //自定JDK默认的线程池,并且存在返回值
        CompletableFuture<Integer> futureJ = CompletableFuture.supplyAsync(() -> 1);
        System.out.println(Thread.currentThread().getName() + "futureJ.get() = " + futureJ.get());

        //whenComplete与exceptionally方法
        //whenComplete可以处理正常和异常的计算结果,另一个方法为whenCompleteAsync
        CompletableFuture<Integer> futureC = CompletableFuture.supplyAsync(() -> 10/0, executor).whenComplete((res, exception) -> {
            System.out.println("res:" + res + "exception:" + exception);
        }).exceptionally((exception)->{
            //exceptionally处理异常情况
            System.out.println("exception = " + exception);
            //发生异常的时候可以设置返回的默认值
            return 100;
        });

        System.out.println("futureC.get() = " + futureC.get());
        /**
         * whenComplete是执行当前任务的线程继续执行whenComplete的任务
         * whenCompleteAsync是whenCompleteAsync执行的内容当作一个新的任务提交给线程池。
         * 不以Async结尾的方法意味着与之前的任务使用同一个线程执行。
         * 以Async结尾的方法意味着使用其他线程执行,当使用的线程池相同的时候也可能会被同一个线程选中执行。
         **/

        //handle方法
        /**
         * whenComplete 一样,可对结果做最后的处理(可处理异常),可改变返回值。
         * 以Async和不以Async结尾任务的执行同whenComplete
         */
        CompletableFuture<Integer> futureH = CompletableFuture.supplyAsync(()->10/0,executor).handleAsync((res,exception)->{
            if (res != null) {
                res += res;
            }
            if (exception != null) {
                res = 100;
            }
            return res;
        },executor);

        System.out.println("futureH.get() = " + futureH.get());

        /**
         * thenApply 方法:当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前 任务的返回值。
         * thenAccept 方法:消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
         * thenRun 方法:只要前面的任务执行完成,就开始执行thenRun,带有 Async 默认是异步执行的。同之前。 这些方法都要前置任务成功完成。
         * Function<? super T,? extends U> T:上一个任务返回结果的类型 U:当前任务的返回值类型
         */
        //线程串行化方法
        CompletableFuture<Integer> futureP = CompletableFuture.supplyAsync(()->10,executor).thenApplyAsync((input)-> input*input,executor);
        System.out.println("futureP = " + futureP.get());

        CompletableFuture.supplyAsync(()->10,executor).thenAcceptAsync(res->{
            System.out.println("res = " + res);
        },executor);

        CompletableFuture.supplyAsync(()->10,executor).thenRunAsync(new Thread(),executor);

        /**
         * 两个任务必须都完成,触发该任务。
         * thenCombine:组合两个 future,获取两个 future 的返回结果,并返回当前任务的返回值
         * thenAcceptBoth:组合两个 future,获取两个 future 任务的返回结果,然后处理任务,没有 返回值。
         * runAfterBoth:组合两个 future,不需要获取 future 的结果,只需两个 future 处理完任务后, 处理该任务。
         */
        //2个任务都要完成
        CompletableFuture<Integer> futureOne = CompletableFuture.supplyAsync(()->10,executor);
        CompletableFuture<String> futureTwo = CompletableFuture.supplyAsync(()->"String",executor);
        CompletableFuture<String> future = futureOne.thenCombineAsync(futureTwo, (res1, res2) -> res1 + res2, executor);
        System.out.println("future = " + future.get());

        futureTwo.thenAcceptBothAsync(futureOne,(res1,res2)->{
            System.out.println("res1:" + res1 + "res2:" +res2 );
        },executor);

        futureTwo.runAfterBothAsync(futureOne,new Thread(),executor);

        /**
         * 当两个任务中,任意一个 future 任务完成的时候,执行任务。
         * applyToEither:两个任务有一个执行完成,获取它的返回值,处理任务并有新的返回值。
         * acceptEither:两个任务有一个执行完成,获取它的返回值,处理任务,没有新的返回值。
         * runAfterEither:两个任务有一个执行完成,不需要获取 future 的结果,处理任务,也没有返 回值。
         **/
        CompletableFuture<Integer> futureThree = CompletableFuture.supplyAsync(()->100,executor);

        CompletableFuture<Integer> futureAE = futureOne.applyToEitherAsync(futureThree, (res) -> res, executor);
        System.out.println("futureAE = " + futureAE.get());

        futureOne.acceptEitherAsync(futureThree,res->{
            System.out.println("哈哈");
        },executor);

        futureThree.runAfterEitherAsync(futureOne,()->{
            System.out.println("呼呼");
        },executor);

        //get()阻塞等待所有任务完成
        CompletableFuture.allOf(future,futureAE).get();
        //任意一个任务完成即可
        Object o = CompletableFuture.anyOf(future, futureOne, futureTwo).get();
        System.out.println("o = " + o.toString());

三 结果展示

pool-1-thread-1
ForkJoinPool.commonPool-worker-1
mainfutureE.get() = 1
mainfutureJ.get() = 1
res:nullexception:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
exception = java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
futureC.get() = 100
futureH.get() = 100
futureP = 100
res = 10
future = 10String
res1:Stringres2:10
futureAE = 10
o = 10String
呼呼
哈哈

       注意

         applyToEitherAsync中的两个任务的返回值要相同,否则会出现上图提示信息。

        时间原因,暂时如此,后续再来整理,麻烦可以耐心等待。。。

异步线程池 & 异步编排 异步线程池 & 异步编排 线程回顾 初始化线程的四种方式 继承Thread public class ThreadTest{ public static class Thread01 extends Thread { @Override public void run() { System.out.println("当前线程:" + Thread.currentThread().getId()); int i = 阅读详情

相关推荐

【Java硬核知识:多线程编程硬核生存指南】CompletableFuture避坑指南:异步编排的优雅与陷阱

摘要:本文聚焦于 Java 中 CompletableFuture 的使用,深入剖析了其在异步编排过程中的各种特性与潜在陷阱。详细阐述了 thenApply 与 thenCompose 的区别,涵盖同步与异步的应用场景;揭示了默认线程池存在的问题,并给出自定义线程池的配置方法;同时介绍了 orTimeout 与 completeOnTimeout 实现超时控制的方式。通过丰富的实操流程和完整代码示例,帮助开发者全面掌握 CompletableFuture 的使用,避免在实际开发中陷入陷阱。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 999

JAVA8多线程-CompletableFuture+Executor

两种创建CompletableFuture的方式: ①:CompletableFuture.supplyAsync(执行有返回值的方法) CompletableFuture codeFuture = CompletableFuture.supplyAsync(() -> loginService.getCode() ); ②:CompletableFuture.runAsync(执行无返回值的方法) Completabl

weixin_45723088的博客 1381

从AD到HFSS:Gerber文件驱动的PCB三维电磁仿真全流程解析

本文详细解析了从AD到HFSS的Gerber文件驱动的PCB三维电磁仿真全流程,重点介绍了Gerber文件作为桥梁的重要性、AD端Gerber文件导出实战指南、HFSS 3D Layout导入技巧及高级问题排查方法。通过实际案例和技巧分享,帮助工程师高效完成PCB电磁仿真,提升设计验证效率。

weixin_33735077的博客 259

CompletableFuture任务编排

多线程、CompletableFuture任务编排

囚徒之困 1031

ArcGIS新手必看:5分钟搞定等高线转DEM栅格(附完整操作截图)

本文详细介绍了在ArcGIS中将等高线转换为DEM栅格的完整流程,包括CAD数据预处理、TIN转栅格和直接插值法两种核心方法,以及常见问题排查与优化技巧。通过实战案例和操作截图,帮助GIS新手快速掌握这一测绘数据处理的核心技能,提升地形分析和三维可视化效率。

dapp9builder的博客 286

Windows10下RTABMAP+T265实现三维建图

win10+rtabmap+t265扫描地形

Suxiang1997的博客 3486

并发编程之CompletableFuture异步编排的详细介绍和基本使用(全网最细最全)

CompletableFutyre异步编排最详细介绍和所有用法的举例说明(附源码),全网最全最细

m0_56466015的博客 5375

别再死记硬背了!用‘瞬时极性法’5分钟搞定三极管反馈电路类型判断

本文介绍了使用‘瞬时极性法’快速判断三极管反馈电路类型的高效技巧。通过假设输入信号变化并追踪传递路径,该方法能准确区分正负反馈、电压电流反馈、串联并联反馈及交直流反馈,避免传统死记硬背的弊端,显著提升电路分析效率。

weixin_42524708的博客 182

JUC---初识CompletableFuture异步编程

CompletableFuture异步编程

qq_40823910的博客 467

静态时序分析(STA)_深入解析Data to Data Checks的零周期挑战

本文深入解析了静态时序分析(STA)中Data to Data Checks的核心概念与零周期挑战。重点探讨了当Setup要求值超过时钟周期时,工具如何调整发射沿,并导致Hold检查的发射与捕获沿“分裂”这一反直觉现象。文章通过案例详细解读了时序报告,并提供了通过调整约束或接受多周期保持两种策略来应对这一挑战,帮助工程师正确理解和处理此类复杂时序检查。

weixin_29204205的博客 349

【华为OD技术面试手撕真题】1、长度最小的子数组 | 手撕真题+思路参考+代码解析(C & C++ & Java & Python & JS)(三种解法)

【华为OD面试手撕真题】长度最小的子数组,本专栏更新每年华为OD机试的高频手撕代码题,每个题目都会使用五种语言进行解答(C & C++& Java & Python & JS),思路分析都非常详细, 实现最低的时间复杂度和高通过率,每个解题思路超过百字,内含各个编程语言的八股文面试题,欢迎大家订阅学习, 代码可以直接运行使用,全网限时最低价,持续更新

KJ.JK 1万+

浅谈CompletableFuture

到这里,你可能懵逼了,那这个CompletionStage定义了那么多方法,到底是干啥用的?异步线程又为何会回调它传入的函数接口的方法呢,BiConsumer#accept()明明不是Runnable#run()、Callable#call()呀!

smart_an的专栏 2432

DAF-Net:动态注意力红外-可见光图像融合

DAF-Net 红外-可见光融合链路:IR/VIS 双分支 (Conv+ResBlock → 64ch) → DynamicAttentionFusion (Cat→Sigmoid→加权) → 重建 (Conv→Sigmoid)。TNO 上 SSIM=0.782 (vs IR), 0.734 (vs VIS), 参数量仅 218K。核心贡献:轻量动态注意力门控, 无监督 SSIM+MSE 损失不需要配准 ground truth。

FJN110的博客 318

【Gulimall+】异步编排 & 线程池

文章目录线程回顾初始化线程的 4 种方式线程池的 7 大参数常见的 4 种线程池开发中为什么使用线程池CompletableFuture 异步编排创建异步对象计算完成时回调方法handle 方法线程串行方法两任务组合 - 都要完成两任务组合 - 一个完成多任务组合商品详情获取 线程回顾 初始化线程的 4 种方式 1、继承 Thread 2、实现 Runnable 3、实现 Callable 接口 + FutureTask(可以拿到返回结果,可以处理异常) 4、线程池 方式一和方式二 主进程无法获取线程的运算

qq_40265247的博客 514

YOLOv8进阶实战:融合SAHI超推理算法,在无人机应用中精准捕捉视频与图片中的微小目标

YOLOv8改进是一种先进的目标检测算法,通过引入辅助超推理算法SAHI推理,使得小目标无法逃避检测。SAHI推理算法结合视频和图片的特点,利用先进的超推理技术,提高了目标检测的准确性和鲁棒性。不仅如此,YOLOv8改进还支持对视频和图片进行实时的目标检测,将检测结果直观地呈现给用户。这一技术的应用范围广泛,可以用于安防领域,提升监控设备的性能和效率;也可以用于无人驾驶领域,实现精准的目标识别和跟踪。总之,YOLOv8改进是一项具有突破性的技术,为目标检测领域带来了重大的进展。

weixin_51988935的博客 807

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

异步-CompletableFuture详解

1.0 线程回顾 1.1 初始化线程的4中方式 继承Thread 实现Runnable接口 实现Callable 接口+FutureTask (可以拿到返回结果,可以处理异常) 线程池 通过线程池性能稳定,也可以获取执行结果,并捕获异常。但是,在业务复杂情况下,一个异步调用可能会依赖于另一个异步调用的执行结果。 import java.util.concurrent.*; public class ThreadTest { public static ExecutorService ser

weixin_42506047的博客 639

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

谷粒微服务高级篇学习笔记整理---异步&线程池

Future 是 Java 5 添加的类,用来描述一个异步计算的结果。可以使用isDone方法检查计算是否完成,或者使用get阻塞住调用线程,直到计算完成返回结果,也可以使用cancel 方法停止任务的执行。虽然Future以及相关使用方法提供了异步执行任务的能力,但是对于结果的获取却是很不方便,只能通过阻塞或者轮询的方式得到任务的结果。阻塞的方式显然和我们的异步编程的初衷相违背。

weixin_72090484的博客 1448

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

线程基础和CompletableFuture异步编排

程基础和CompletableFuture异步编排

m0_62946761的博客 2571

【谷粒商城之CompletableFuture异步编排】

在 Java 8 中, 新增加了一个包含 50 个方法左右的类: CompletableFuture,提供了非常强大的Future 的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提供了转换和组合 CompletableFuture 的方法。CompletableFuture 类实现了 Future 接口,所以你还是可以像以前一样通过get方法阻塞或者轮询的方式获得结果,但是这种方式不推荐使用。

蛋饼吧的博客 1416

Java多线程--CompletableFuture异步编排

举一个形象的例子: 在一个方法中实现了A、B、C三个功能,假设每个功能的执行所需要的时间分别为(5s,10s,15s),在没有异步编排之前,进入方法依次执行 A功能—>B功能—>C功能,执行方法完毕,用时30s。当我们在方法中引入异步编排,给A、B、C每个功能都分配一个不同的线程执行,这样的情况下,最快15s这个方法就可以执行完毕,这就是所谓的异步。.........

sunao1106的博客 1127

CompletableFuture 异步编排

CompletableFuture 异步编排

江黎 437

CompletableFuture 异步编排、案例及应用小案例

今天的话,就来以一个应用场景来进行一步一步的推导,在实现案例的过程中,将相关的知识点逐步讲述明白。应用场景如下:我们在查询掘金文章页面数据为应用场景,如何使用异步编程进行优化。//1. 文章内容信息 1s//2. 作者相关信息 0.5s 依赖于1的查询结果//3. 文章评论信息 0.5s 依赖于1的查询结果//4. 文章分类信息 0.5s 依赖于1的查询结果//5. 文章专栏信息 0.5s 依赖于1的查询结果//6. 相关文章信息 0.5s 依赖于1的查询结果//...补充。

java_lujj的博客 290

CompletableFuture异步编排

一、线程&线程池回顾 import java.util.concurrent.*; public class ThreadTest { // 当前系统中线程池只有1-2个,每个异步任务,提交给线程池去执行 public static ExecutorService service = Executors.newFixedThreadPool(10); public static void main(String[] args) { /*

冷兮Coding 391

异步编排CompletableFuture的运用

1. 线程回顾 初始化线程的4种方式: 继承Thread 实现Runnable接口 实现Callable接口 + FutureTask (可以拿到返回结果,可以处理异常) 线程池 方式1和方式2:主进程无法获取线程的运算结果。不适合当前场景 方式3:主进程可以获取线程的运算结果,并设置给itemVO,但是不利于控制服务器中的线程资源。可以导致服务器资源耗尽。 方式4:通过如下两种方式初始化线程池: Executors.newFiexedThreadPool(3); //或者 new ThreadPo

qq_45916834的博客 521

【Java】CompletableFuture:异步编排、异常处理与生产级熔断实现

本文深入解析Java 8的CompletableFuture异步编程框架,涵盖核心概念、异步编排技巧和异常处理机制。重点介绍了单链式编排(thenApply/thenCompose)和多任务合并(thenCombine/allOf/anyOf)的实现方式,通过实际案例展示并行调用微服务的应用场景。文章特别强调线程池配置的重要性,并详细讲解异常传播机制及两种处理策略(exceptionally/handle)。最后还提及生产环境中的超时控制和熔断保护实现,为构建健壮的异步系统提供实践指导。

瘦到被风吹走的博客 300
上一篇: Executors构建线程池的不足
下一篇: -bash: ifconfig: command not found
至学者
博客等级 码龄9年 180粉丝 773原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值