java 8 新特性CompletableFuture使用

准备工作:定义一个线程池

        ExecutorService pool= Executors.newFixedThreadPool(3,(Runnable r)->{Thread t=new Thread(r);t.setDaemon(true);return t;});

一、执行方式
1、对于有返回值的

CompletableFuture<String> future=CompletableFuture.supplyAsync(()->{return "主任务返回结果";},pool).handle((result,throwable)->{if(throwable!=null){return "处理异常结果";}System.out.println("结果回调");System.out.println(result);return "统一返回结果:"+result;});String result=future.get();System.out.println(result);

2、对应没有返回值的

ExecutorService pool= Executors.newFixedThreadPool(3,(Runnable r)->{Thread t=new Thread(r);t.setDaemon(true);return t;});CompletableFuture<Void> future=CompletableFuture.runAsync(()->{System.out.println("业务1");System.out.println("业务2");},pool);future.join();

二、设置回调

CompletableFuture<String> future=CompletableFuture.supplyAsync(()->{System.out.println("业务1");return "11111";},pool).whenComplete((v,throwable)->{System.out.println("回调结果");System.out.println(v);});future.join();

三、异步任务的串行:
即流水线方式,一个任务结束另一个任务开始执行
1、thenApplyAsync方式:第一个任务结束,第二个任务用第一个任务的结果作为参数,并开启第二个任务的执行,第二个任务返回新的结果。

CompletableFuture<String> funtue=CompletableFuture.supplyAsync(()->"a",pool).thenApplyAsync(v->{System.out.println("主任务结果"+v);return "b";},pool).thenApplyAsync(v->{System.out.println("次任务结果"+v);return "c";},pool);System.out.println(funtue.get());

2、thenRunAsync:第一个任务结束,第二个任务开始,并且第二个任务无需参数(与上一个任务执行结果无关),并且第二个任务无返回值

CompletableFuture<Void> funtue=CompletableFuture.supplyAsync(()->"a",pool).thenRunAsync(()->{System.out.println("谢谢小星星");System.out.println("异步执行");},pool);funtue.join();

3、thenAcceptAsync:第一个任务结束,第二个任务用第一个任务的结果作为参数,并开启第二个任务的执行,第二个任务无返回值。

CompletableFuture<Void> funtue=CompletableFuture.supplyAsync(()->"a",pool).thenAcceptAsync(v->{System.out.println("上一步结果");System.out.println(v);},pool);funtue.join();

4、thenComposeAsync:与thenApplyAsync类似,不同的是第二个任务的返回结果是CompletableFuture类型的

        CompletableFuture<String> funtue=CompletableFuture.supplyAsync(()->"a",pool).thenComposeAsync(v->{System.out.println("上一步计算结果:"+v);return CompletableFuture.supplyAsync(()->"b",pool);},pool);System.out.println(funtue.get());

四、异步任务的合并执行:

例如一共有三个任务,第三个任务需要再第一个任务和第二个任务都执行完成后才能执行第三个任务
1、thenCombineAsync:调用方为第一个任务的CompletionStage,第一个参数为第二个任务的CompletionStage。在第一个和第二个任务都执行完成后,开始执行第三个任务,第三个任务的参数分别为第一个、第二个任务的返回结果,并且第三个任务需要返回新的结果

CompletableFuture<Integer> future1=CompletableFuture.supplyAsync(()->3,pool);CompletableFuture<Integer> future2=CompletableFuture.supplyAsync(()->6,pool);CompletableFuture<Integer> future3=future1.thenCombineAsync(future2,(m,v)->m*v,pool);System.out.println(future3.get());

2、runAfterBothAsync::调用方为第一个任务的CompletionStage,第一个参数为第二个任务的CompletionStage。在第一个和第二个任务都执行完成后,开始执行第三个任务,第三个任务与第一个、第二个任务的返回结果无关,即没有参数,并且第三个任务无返回值。

CompletableFuture<Void> future1=CompletableFuture.runAsync(()-> System.out.println("步骤1"),pool);CompletableFuture<Void> future2=CompletableFuture.runAsync(()->System.out.println("步骤2"),pool);CompletableFuture<Void> future3=future1.runAfterBothAsync(future2,()->System.out.println("步骤3"),pool);future3.join();

3、thenAcceptBothAsync:调用方为第一个任务的CompletionStage,第一个参数为第二个任务的CompletionStage。在第一个和第二个任务都执行完成后,开始执行第三个任务,第三个任务的参数分别为第一个、第二个任务的返回结果,并且第三个任务无返回值。

CompletableFuture<Integer> future1=CompletableFuture.supplyAsync(()->3,pool);CompletableFuture<Integer> future2=CompletableFuture.supplyAsync(()->6,pool);CompletableFuture<Void> future3=future1.thenAcceptBothAsync(future2,(m,n)->{System.out.println(m);System.out.println(n);},pool);future3.join();

4、allOf:等待所有异步任务执行完成

CompletableFuture<Integer> future1=CompletableFuture.supplyAsync(()->3,pool);CompletableFuture<Integer> future2=CompletableFuture.supplyAsync(()->6,pool);CompletableFuture<Integer> future3=CompletableFuture.supplyAsync(()->9,pool);CompletableFuture<Void> future4=CompletableFuture.allOf(future1,future2,future3);future4.join();System.out.println(future1.get());System.out.println(future2.get());System.out.println(future3.get());

五、异步任务的选择执行:
例如有三个任务,第三个任务需要在第一个任务和第二个任务中执行快的那一个执行完成后,才可以执行任务三
1、applyToEitherAsync:在任务一、任务二中,只要有一个任务先执行完成后,将执行快的那个任务的返回结果作为第三个任务的参数,然后才可执行任务三,并且任务三需要返回新的结果

CompletableFuture<Integer> future1=CompletableFuture.supplyAsync(()->{try {Thread.sleep(9000);return 3;} catch (InterruptedException e) {throw new RuntimeException(e);}},pool);CompletableFuture<Integer> future2=CompletableFuture.supplyAsync(()->{try {Thread.sleep(6000);return 6;} catch (InterruptedException e) {throw new RuntimeException(e);}},pool);CompletableFuture<Integer> future3=future1.applyToEitherAsync(future2,v->v,pool);System.out.println(future3.get());

2、runAfterEitherAsync:在任务一、任务二中,只要有一个任务先执行完成后,再执行任务三,并且任务三无参数和返回值

CompletableFuture<Void> future1=CompletableFuture.runAsync(()->{try {Thread.sleep(3000);System.out.println("任务1");} catch (InterruptedException e) {throw new RuntimeException(e);}},pool);CompletableFuture<Void> future2=CompletableFuture.runAsync(()->{try {Thread.sleep(6000);System.out.println("任务2");} catch (InterruptedException e) {throw new RuntimeException(e);}},pool);CompletableFuture<Void> future3=future1.runAfterEitherAsync(future2,()-> System.out.println("任务3"),pool);System.out.println(future3.join());

3、acceptEitherAsync:在任务一、任务二中,只要有一个任务先执行完成后,将执行快的那一个任务的返回结果作为第三个任务的参数,然后才可执行任务三,并且任务三无需返回值

CompletableFuture<Integer> future1=CompletableFuture.supplyAsync(()->{try {Thread.sleep(3000);return 3;} catch (InterruptedException e) {throw new RuntimeException(e);}},pool);CompletableFuture<Integer> future2=CompletableFuture.supplyAsync(()->{try {Thread.sleep(6000);return 6;} catch (InterruptedException e) {throw new RuntimeException(e);}},pool);CompletableFuture<Void> future3=future1.acceptEitherAsync(future2,v-> System.out.println(v),pool);System.out.println(future3.join());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/849895.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Swift 序列(Sequence)排序面面俱到 - 从过去到现在(一)

概览 在任何语言中对序列(或集合)元素的排序无疑是一种司空见惯的常规操作,在 Swift 语言里自然也不例外。序列排序看似简单,实则“暗藏玄机”。 要想真正掌握 Swift 语言中对排序的“各种姿势”,我们还得从长计议。不如就先从最简单的排序基本功开始聊起吧。 在本篇博…

【十大排序算法】插入排序

插入排序&#xff0c;如一位细心的整理者&#xff0c; 她从序列的左端开始&#xff0c; 挨个将元素归位。 每当她遇到一个无序的元素&#xff0c; 便将它插入已经有序的部分&#xff0c; 直至所有元素有序排列。 她不张扬&#xff0c;却有效率&#xff0c; 用自己的方式&…

探索HTML5新Input类型:重塑表单交互的未来

随着HTML5标准的演进&#xff0c;表单设计迎来了重大革新&#xff0c;其中最引人注目的莫过于一系列新的input类型。这些新类型不仅简化了前端开发&#xff0c;提升了用户体验&#xff0c;还增强了网页表单的数据验证能力。然而&#xff0c;值得注意的是&#xff0c;不同浏览器…

什么是umi

UMI&#xff08;Umi Next.js Inspired Middleware&#xff09;是一个基于 React 的企业级前端应用框架&#xff0c;由阿里巴巴团队开发和维护。UMI 框架结合了 React、Webpack、Babel、Dva&#xff08;一个基于 Redux 和 redux-saga 的数据流方案&#xff09;等主流前端技术&am…

pdf文件在线压缩网站,pdf文件在线压缩工具软件

在数字化时代的今天&#xff0c;PDF文件已经成为我们日常生活和工作中不可或缺的一部分。然而&#xff0c;随着PDF文件的广泛使用&#xff0c;其文件大小问题也日益凸显。过大的PDF文件不仅占用了大量的存储空间&#xff0c;而且在传输和共享过程中也往往面临诸多不便。因此&am…

SylixOS网卡多 IP 配置

概述 网卡多 IP 是指在同一个网络接口上配置和绑定多个 IP 地址。 引进网卡多 IP 的目的主要有以下几个&#xff1a; 提供服务高可用性。通过在同一接口绑定多个 IP 地址&#xff0c;然后在服务端使用这些 IP 地址启动多个服务实例。这样在任意一 IP 出现问题时&#xff0c;可…

Redis学习(十二)Redis的三种删除策略

目录 一、背景二、Redis 的三种删除策略2.1 定时删除&#xff08;用CPU换内存空间&#xff09;2.2 定期删除2.3 惰性删除&#xff08;用内存换CPU性能&#xff09; 三、总结 一、背景 我们都知道 Redis 是一种内存数据&#xff0c;所有的数据均存储在内存中&#xff0c;可以通…

Android 代码打印meminfo

旨在替代adb shell dumpsys meminfo packageName&#xff0c;在log打印meminfo&#xff0c;以便分析内存情况 ActivityManager.MemoryInfo memoryInfo new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); long totalMemory Runtime.getRuntime(…

大数据环境搭建@Hive编译

Hive3.1.3编译 1.编译原因1.1Guava依赖冲突1.2开启MetaStore后运行有StatsTask报错1.3Spark版本过低 2.环境部署2.1jdk安装2.2maven部署2.3安装图形化桌面2.4安装Git2.5安装IDEA 3.拉取Hive源码4.Hive源码编译4.1环境测试1.测试方法——编译2.问题及解决方案&#x1f4a5;问题1…

【设计模式】结构型-装饰器模式

在代码的海洋深处迷离&#xff0c;藏匿着一片神奇之地。那里有细腻的线条交错&#xff0c;是装饰器的奇妙艺术。 文章目录 一、登录的困境二、装饰器模式三、装饰器模式的核心组成部分四、运用装饰器模式五、装饰器模式的应用场景六、小结推荐阅读 一、登录的困境 假设我们有…

如何使用Vue模块实现电子书管理系统的分类管理功能?

如何使用Vue模块实现电子书管理系统的分类管理功能&#xff1f; 在开发电子书管理系统时&#xff0c;分类管理是一个非常重要的功能。本文将介绍如何使用Vue模块来实现这个功能。以下是具体的实现步骤&#xff1a; 1. 新增工具文件 首先&#xff0c;我们需要在util包下建立一…

YOLOv5改进总目录 | backbone、Neck、head、损失函数,注意力机制上百种改进技巧

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏地址&#xff1a; YOLOv5改进入门——持续更新各种有效涨点方法 点击即可跳转 报错 解决Yolov5的RuntimeError: result type Float can…

qq号码采集软件

寅甲QQ号码采集软件, 一款采集QQ号、QQ邮件地址&#xff0c;采集QQ群成员、QQ好友的软件。可以按关键词采集&#xff0c;如可以按地区、年龄、血型、生日、职业等采集。采集速度非常快且操作很简单。

C# WPF入门学习主线篇(九)—— ComboBox常见属性和事件

欢迎来到C# WPF入门学习系列的第九篇。在前面的文章中&#xff0c;我们已经学习了 Button、TextBox、Label 和 ListBox 控件。今天&#xff0c;我们将探讨 WPF 中的另一个重要控件——ComboBox。本文将详细介绍 ComboBox 的常见属性和事件&#xff0c;并通过示例代码展示其在实…

逻辑这回事(三)----时序分析与时序优化

基本时序参数 图1.1 D触发器结构 图1.2 D触发器时序 时钟clk采样数据D时&#xff0c;Tsu表示数据前边沿距离时钟上升沿的时间&#xff0c;MicTsu表示时钟clk能够稳定采样数据D的所要求时间&#xff0c;Th表示数据后边沿距离时钟上升沿的时间&#xff0c;MicTh表示时钟clk采样…

Spring Boot集成pmd插件快速入门Demo

1.什么是pmd插件&#xff1f; PMD 插件允许您在项目的源代码上自动运行PMD代码分析工具&#xff0c;并生成带有其结果的站点报告。它还支持与 PMD 一起分发的单独的复制/粘贴检测器工具&#xff08;或 CPD&#xff09;。 此版本的 Maven PMD 插件使用 PMD 6.42.0 并且需要 Jav…

从大到小吗?-分支c++

题目描述 给出 4 个整数&#xff0c;a , b , c , d 。 判断这四个数字是否满足从大到小。 输入 输入 4 个整数&#xff0c;a , b , c , d 。 输出 输出 Yes 或者 No 。 样例输入 4 3 2 1 样例输出 Yes 提示 分析&#xff1a; 这道题十分的简单&#xff0c;只需判断…

23 二叉搜索树

本节目标 1.内容安排说明 2.二叉搜索树实现 3.应用分析 4.进阶题 1. 内容安排说明 二叉树在c数据结构已经说过了&#xff0c;本节内容是因为&#xff1a; map和set特性需要先铺垫二叉搜索树&#xff0c;而二叉搜索树也是一种树形结构二叉搜索树的特性了解&#xff0c;有助于…

Linux:动态库和静态库的编译与使用

目录 1.前言 2.静态链接库 3.静态链接库生成步骤 4.静态链接库的使用 5.动态链接库 6.动态链接库生成步骤 7.动态链接库的使用 8.动态链接库无法加载 9.解决动态链接库无法加载问题 前言 在《MinGW&#xff1a;从入门到链接库》博客中简单介绍了如何编译动态链接库和静态链接库…

YOLOv5车流量监测系统研究

一. YOLOv5算法详解 YOLOv5网络架构 上图展示了YOLOv5目标检测算法的整体框图。对于一个目标检测算法而言&#xff0c;我们通常可以将其划分为4个通用的模块&#xff0c;具体包括&#xff1a;输入端、基准网络、Neck网络与Head输出端&#xff0c;对应于上图中的4个红色模块。Y…