当前位置: 首页 > news >正文

CompletableFuture常用方法

一、获得结果和触发计算

1.获取结果
(1)public T get()
public class CompletableFutureAPIDemo{public static void main(String[] args) throws ExecutionException, InterruptedException{CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}return "abc";});//get():阻塞1s后返回结果(必须得到结果)System.out.println(completableFuture.get());}
}

运行结果:

(2)public T get(long timeout,TimeUnit unit)
public class CompletableFutureAPIDemo{public static void main(String[] args) throws ExecutionException, InterruptedException{CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return "abc";});//get(2L,TimeUnit.SECONDS):只等待2s,2s没有获取到结果抛出System.out.println(completableFuture.get(2L,TimeUnit.SECONDS));}
}

运行结果:

(3)public T join()
public class CompletableFutureAPIDemo{public static void main(String[] args){CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}return "abc";});//join():和get()一致,但是不抛出异常System.out.println(completableFuture.join());}
}

运行结果:

(4)public T getNow(T valueIfAbsent)
public class CompletableFutureAPIDemo{public static void main(String[] args){CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return "abc";});///暂停几秒钟线程try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}//getNow(T valueIfAbsent)//没有计算完成的情况下,给我一个替代结果//立即获取结果不阻塞,计算完返回结果,没计算完返回替代结果//也不需要抛出异常System.out.println(completableFuture.getNow("xyz"));}
}

运行结果:

2.主动触发计算
(1)public boolean complete(T value)
public class CompletableFutureAPIDemo{public static void main(String[] args) throws ExecutionException, InterruptedException {CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {//暂停几秒钟线程try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return "abc";});//complete(T value):是否打断get方法立即返回括号值//计算未执行完,打断成功,返回true,返回括号替代值//计算执行完,打断失败,返回false,返回原计算结果System.out.println("是否打断成功:" + completableFuture.complete("xyz"));System.out.println("结果:" + completableFuture.get());}
}

运行结果:

二、对计算结果进行处理

1.thenApply
  • 计算结果存在依赖关系,使两个线程串行化
  • 存在依赖关系(当前报错,不走下一步),当前步骤有异常的话就叫停
public class CompletableFutureAPI2Demo{public static void main(String[] args){ExecutorService threadPool = Executors.newFixedThreadPool(3);CompletableFuture.supplyAsync(() ->{//暂停几秒钟线程try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }System.out.println("111");return 1;},threadPool).thenApply(f -> {int i=10/0;System.out.println("222");return f + 2;}).thenApply(f -> {System.out.println("333");return f + 3;}).whenComplete((v,e) -> {if (e == null) {System.out.println("----计算结果: "+v);}}).exceptionally(e -> {e.printStackTrace();System.out.println(e.getMessage());return null;});System.out.println(Thread.currentThread().getName()+"----主线程正在执行其他任务");threadPool.shutdown();}
}

结果:

2.handle
  • 计算结果存在依赖关系,这两个线程串行化
  • 有异常也可以往下一步走,根据带的异常参数可以进一步处理
public class CompletableFutureAPI2Demo{public static void main(String[] args){ExecutorService threadPool = Executors.newFixedThreadPool(3);CompletableFuture.supplyAsync(() ->{//暂停几秒钟线程try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }System.out.println("111");return 1;},threadPool).handle((f,e) -> {int i=10/0;System.out.println("222");return f + 2;}).handle((f,e) -> {System.out.println("333");return f + 3;}).whenComplete((v,e) -> {if (e == null) {System.out.println("----计算结果: "+v);}}).exceptionally(e -> {e.printStackTrace();System.out.println(e.getMessage());return null;});System.out.println(Thread.currentThread().getName()+"----主线程正在执行其他任务");threadPool.shutdown();}
}

结果:

三、对计算结果进行消费

1.thenAccept
  • 接受任务的处理结果,并消费处理,无返回结果
public class CompletableFutureApi2Demo {public static void main(String[] args) {ExecutorService threadPool = Executors.newFixedThreadPool(3);CompletableFuture.supplyAsync(() -> {return 1;}, threadPool).thenApply(f -> {return f + 2;}).thenApply(f -> {return f + 2;}).thenAccept(r -> {System.out.println(r);//5});}
}

结果:

2.对比补充
  • thenRun(Runnable runnable) :任务A执行完执行B,并且不需要A的结果
  • thenAccept(Consumer action): 任务A执行完执行B,B需要A的结果,但是任务B没有返回值
  • thenApply(Function fn): 任务A执行完执行B,B需要A的结果,同时任务B有返回值
public class CompletableFutureApi2Demo {public static void main(String[] args) {System.out.println(CompletableFuture.supplyAsync(() -> "result").thenRun(() -> {}).join());//nullSystem.out.println(CompletableFuture.supplyAsync(() -> "result").thenAccept(r -> System.out.println(r)).join());//result nullSystem.out.println(CompletableFuture.supplyAsync(() -> "result").thenApply(f -> f + 2).join());//result2}
}

结果:

3.CompletableFuture和线程池说明
  • 如果没有传入自定义线程池,都用默认线程池ForkJoinPool
  • 传入一个线程池,如果你执行第一个任务时,传入了一个自定义线程池
    • 调用thenRun方法执行第二个任务时,则第二个任务和第一个任务时共用同一个线程池
    • 调用thenRunAsync执行第二个任务时,则第一个任务使用的是你自定义的线程池,第二个任务使用的是ForkJoin线程池
    • 备注:可能是线程处理太快,系统优化切换原则, 直接使用main线程处理,thenAccept和thenAcceptAsync,thenApply和thenApplyAsync等,之间的区别同理。(方法名后面有无Async的区别是,有Async的方法在底层会调用uniRunStage(asyncPool,action);方法,将线程池更改为ForkJoinPool而不是自定义线程池

四、对计算速度进行选用

1.applyToEither
  • 用于在两个 CompletableFuture 中任何一个完成时,执行某个函数。它允许我们并行执行两个异步任务,并在任意一个任务完成后,立即对结果进行处理,而无需等待另一个任务完成。 (谁快用谁)
public class CompletableFutureApiDemo {public static void main(String[] args) {ExecutorService threadPool = Executors.newFixedThreadPool(3);CompletableFuture<String> playA = CompletableFuture.supplyAsync(() -> {try {System.out.println("A come in");TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return "playA";}, threadPool);CompletableFuture<String> playB = CompletableFuture.supplyAsync(() -> {try {System.out.println("B come in");TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return "playB";}, threadPool);CompletableFuture<String> result = playA.applyToEither(playB, f -> {return f + " is winner";});/*** A come in* B come in* main-----------winner:playA is winner*/System.out.println(Thread.currentThread().getName() + "-----------winner:" + result.join());}
}

结果:

五、对计算结果进行合并

1.thenCombine
  • 用于将两个异步任务的结果组合在一起并执行某个操作。它会等待两个 CompletableFuture 都完成后,再将它们的结果一起传递给一个指定的函数进行处理。
public class CompletableFutureApi3Demo {public static void main(String[] args) {CompletableFuture<Integer> completableFuture1 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + " 启动");try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}return 10;});CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + " 启动");try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return 20;});CompletableFuture<Integer> finalResult = completableFuture1.thenCombine(completableFuture2, (x, y) -> {System.out.println("----------开始两个结果合并");return x + y;});System.out.println(finalResult.join());}
}

结果:

相关文章:

CompletableFuture常用方法

一、获得结果和触发计算 1.获取结果 &#xff08;1&#xff09;public T get() public class CompletableFutureAPIDemo{public static void main(String[] args) throws ExecutionException, InterruptedException{CompletableFuture<String> completableFuture Com…...

本地化测试对游戏漏洞修复的影响

本地化测试在游戏开发的质量保证过程中起着至关重要的作用&#xff0c;尤其是在修复bug方面。当游戏为全球市场做准备时&#xff0c;它们通常会被翻译和改编成各种语言和文化背景。这种本地化带来了新的挑战&#xff0c;例如潜在的语言错误、文化误解&#xff0c;甚至是不同地区…...

使用rust实现rtsp码流截图

中文互联网上的rust示例程序源码还是太稀少&#xff0c;找资料很是麻烦&#xff0c;下面是自己用业余时间开发实现的一个对批量rtsp码流源进行关键帧截图并存盘的rust demo源码记录。 要编译这个源码需要先安装vcpkg&#xff0c;然后用vcpkg install ffmpeg安装最新版本的ffmpe…...

Cpp::STL—string类的模拟实现(12)

文章目录 前言一、string类各函数接口总览二、默认构造函数string(const char* str "");string(const string& str);传统拷贝写法现代拷贝写法 string& operator(const string& str);传统赋值构造现代赋值构造 ~string(); 三、迭代器相关函数begin &…...

一文搞懂SentencePiece的使用

目录 1. 什么是 SentencePiece&#xff1f;2. SentencePiece 基础概念2.1 SentencePiece 的工作原理2.2 SentencePiece 的优点 3. SentencePiece 的使用3.1 安装 SentencePiece3.2 训练模型与加载模型3.3 encode&#xff08;高频&#xff09;3.4 decode&#xff08;高频&#x…...

一个简单的摄像头应用程序1

这个Python脚本实现了一个基于OpenCV的简单摄像头应用,我们在原有的基础上增加了录制视频等功能,用户可以通过该应用进行拍照、录制视频,并查看已拍摄的照片。以下是该脚本的主要功能和一些使用时需要注意的事项: 功能 拍照: 用户可以通过点击界面上的“拍照”按钮或按…...

通过PHP获取商品详情

在电子商务的浪潮中&#xff0c;数据的重要性不言而喻。商品详情信息对于电商运营者来说尤为宝贵。PHP&#xff0c;作为一种广泛应用的服务器端脚本语言&#xff0c;为我们提供了获取商品详情的便捷途径。 了解API接口文档 开放平台提供了详细的API接口文档。你需要熟悉商品详…...

【Android】获取备案所需的公钥以及签名MD5值

目录 重要前提 获取签名MD5值 获取公钥 重要前提 生成jks文件以及gradle配置应用该文件。具体步骤请参考我这篇文章&#xff1a;【Android】配置Gradle打包apk的环境_generate signed bundle or apk-CSDN博客 你只需要从头看到该文章的配置build.gradle&#xff08;app&…...

看480p、720p、1080p、2k、4k、视频一般需要多大带宽呢?

看视频都喜欢看高清,那么一般来说看电影不卡顿需要多大带宽呢? 以4K为例,这里引用一位网友的回答:“视频分辨率4092*2160,每个像素用红蓝绿三个256色(8bit)的数据表示,视频帧数为60fps,那么一秒钟画面的数据量是:4096*2160*3*8*60≈11.9Gbps。此外声音大概是视频数据量…...

解决IDEA中@Autowired红色报错的实用指南:原因与解决方案

前言&#xff1a; 在使用Spring Boot开发时&#xff0c;Autowired注解是实现依赖注入的常用方式。然而&#xff0c;许多开发者在IDEA中使用Autowired时&#xff0c;可能会遇到红色报错&#xff0c;导致代码的可读性降低。本文将探讨导致这种现象的原因&#xff0c;并提供几种解…...

408知识点自检(一)

一、细节题 虚电路是面向连接的吗&#xff1f;虚电路线路上会不会有其他虚电路通过&#xff1f;虚电路适合什么类型的数据交换&#xff1f;虚电路的可靠性靠其他协议还是自己&#xff1f;固态硬盘的优势体现在什么存取方式&#xff1f;中断向量地址是谁的地址&#xff1f;多播…...

负载均衡--相关面试题(六)

在负载均衡的面试中&#xff0c;可能会遇到一系列涉及概念、原理、实践应用以及技术细节的问题。以下是一些常见的负载均衡面试题及其详细解答&#xff1a; 一、什么是负载均衡&#xff1f; 回答&#xff1a;负载均衡是一种将网络请求或数据传输工作分配给多个服务器或网络资源…...

【Unity踩坑】Unity更新Google Play结算库

一、问题描述&#xff1a; 在Google Play上提交了app bundle后&#xff0c;提示如下错误。 我使用的是Unity 2022.01.20f1&#xff0c;看来用的Play结算库版本是4.0 查了一下文档&#xff0c;Google Play结算库的维护周期是两年。现在需要更新到至少6.0。 二、更新过程 1. 下…...

Redis:hash类型

Redis&#xff1a;hash类型 hash命令设置与读取HSETHGETHMGET 哈希操作HEXISTSHDELHKEYSHVALSHGETALLHLENHSETNXHINCRBYHINCRBYFLOAT 内部编码ziplisthashtable 目前主流的编程语言中&#xff0c;几乎都提供了哈希表相关的容器&#xff0c;Redis自然也会支持对应的内容&#xf…...

力扣9.30

1749. 任意子数组和的绝对值的最大值 给你一个整数数组 nums 。一个子数组 [numsl, numsl1, ..., numsr-1, numsr] 的 和的绝对值 为 abs(numsl numsl1 ... numsr-1 numsr) 。 请你找出 nums 中 和的绝对值 最大的任意子数组&#xff08;可能为空&#xff09;&#xff0c…...

kafka下载配置

下载安装 参开kafka社区 zookeeperkafka消息队列群集部署https://apache.csdn.net/66c958fb10164416336632c3.html 下载 kafka_2.12-3.2.0安装包快速下载地址分享 官网下载链接地址&#xff1a; 官网下载地址&#xff1a;https://kafka.apache.org/downloads 官网呢下载慢…...

nlp任务之预测中间词-huggingface

目录 1.加载编码器 1.1编码试算 2.加载数据集 3.数据集处理 3.1 map映射&#xff1a;只对数据集中的sentence数据进行编码 3.2用filter()过滤 单词太少的句子过滤掉 3.3截断句子 4.创建数据加载器Dataloader 5. 下游任务模型 6.测试预测代码 7.训练代码 8.保…...

《程序猿之Redis缓存实战 · Redis 与数据库一致性》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…...

【无标题】observer: error while loading shared libraries: libmariadb.so.3处理办法

文章目录 1.记录新装的oceanbase,使用observer帮助时&#xff0c;出现lib文件无法找到的处理过程 ./observer --help ./observer: error while loading shared libraries: libmariadb.so.3: cannot open shared object file: No such file or directory2.做一个strace跟踪&…...

极客兔兔Gee-Cache Day1

极客兔兔7Days GeeCache - Day1 interface{}&#xff1a;任意类型 缓存击穿&#xff1a;一个高并发的请求查询一个缓存中不存在的数据项&#xff0c;因此这个请求穿透缓存直接到达后端数据库或数据源来获取数据。如果这种请求非常频繁&#xff0c;就会导致后端系统的负载突然…...

告别手动建模!用ArcGIS+SWMM+慧天平台,5步搞定城市内涝模拟(附实战数据)

城市内涝模拟实战&#xff1a;ArcGISSWMM慧天平台高效协同工作流 暴雨过后街道成河、地下车库变泳池的场景&#xff0c;已成为许多城市规划者和工程师的噩梦。传统的内涝模拟方法需要手动处理海量管网数据&#xff0c;不仅耗时费力&#xff0c;还容易在数据转换过程中丢失关键信…...

搞懂VMware三种网络模式:从NAT断网到桥接、仅主机的实战选择指南

VMware虚拟网络模式深度解析&#xff1a;从原理到场景化实战 当你在深夜赶项目时&#xff0c;虚拟机突然无法联网——这种经历对于开发者而言无异于噩梦。我曾亲眼见过团队新人在演示前夜因NAT模式配置问题崩溃&#xff0c;也见证过安全工程师因选错网络模式导致测试环境暴露。…...

从OpenClaw到memU Bot:企业级AI代理的记忆优先架构与实战部署

1. 项目概述&#xff1a;从个人助手到企业级AI代理的跃迁如果你和我一样&#xff0c;是OpenClaw的早期用户&#xff0c;那你一定体验过那种“私人AI管家”带来的便利。它能帮你写邮件、查资料、整理文件&#xff0c;就像一个随时待命的数字伙伴。但当我们尝试在团队内部推广&am…...

如何用Python操控Photoshop?3步实现自动化图像处理的终极指南

如何用Python操控Photoshop&#xff1f;3步实现自动化图像处理的终极指南 【免费下载链接】photoshop-python-api Python API for Photoshop. 项目地址: https://gitcode.com/gh_mirrors/ph/photoshop-python-api Photoshop Python API是一个革命性的工具&#xff0c;让…...

手把手教你:在RT-Thread上用STM32驱动0.96寸OLED显示动态二维码(附完整源码)

基于RT-Thread的STM32动态二维码显示系统开发实战 在智能门锁、工业设备配网等物联网场景中&#xff0c;二维码作为信息载体正发挥着越来越重要的作用。本文将完整呈现如何在RT-Thread操作系统上&#xff0c;通过STM32驱动0.96寸OLED实现动态二维码显示功能。不同于简单的功能演…...

DataX实战避坑:手把手教你用Shell脚本搞定MySQL多表同步(附完整脚本)

DataX多表同步实战&#xff1a;从脚本优化到生产级部署的全链路指南 MySQL数据同步是数据仓库建设中的基础环节&#xff0c;而DataX作为阿里巴巴开源的高效数据同步工具&#xff0c;在实际生产环境中却常常因为脚本设计不当导致维护成本激增。本文将从一个真实电商平台的订单系…...

碧蓝航线Live2D模型提取:3步快速获取游戏角色资源的完整指南

碧蓝航线Live2D模型提取&#xff1a;3步快速获取游戏角色资源的完整指南 【免费下载链接】AzurLaneLive2DExtract OBSOLETE - see readme / 碧蓝航线Live2D提取 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneLive2DExtract 你是否曾经想提取碧蓝航线中精美的Li…...

蓝牙6.0 Channel Sounding 基于接入地址的定时估计原理

基于接入地址的定时估计 先看下core spec的描述&#xff1a;蓝牙Core Spec Vol 6 Part H中 3.2节「基于接入地址的定时估计」&#xff0c;它定义了两种用于CS_SYNC包到达时间&#xff08;ToA&#xff09;估计的方法&#xff0c;是RTT测距的基础定时方案。下面我逐段拆解&#x…...

七、数据与存储

一、 数据库操作 1、QSqlDatabase 连接管理深度剖析 连接生命周期与内部机制 QSqlDatabase 的连接管理不走寻常路——它内部是一个全局静态哈希表,存储着所有命名连接。这带来了几个重要的设计约束: // QSqlDatabase 内部实现的核心数据结构(简化还原)// Qt 源码中通过 QH…...

E-Hentai下载器:免费漫画批量下载工具完整指南

E-Hentai下载器&#xff1a;免费漫画批量下载工具完整指南 【免费下载链接】E-Hentai-Downloader Download E-Hentai archive as zip file 项目地址: https://gitcode.com/gh_mirrors/eh/E-Hentai-Downloader 你是否曾经为了收藏喜欢的漫画而一页一页手动保存&#xff1…...