CompletableFuture

在现代编程中,异步操作是提升程序性能和响应性的关键技术。Java 8 引入的CompletableFuture类,极大地简化了异步编程的复杂性,提供了一种强大且灵活的方式来处理异步任务及其结果。本文将深入探讨CompletableFuture的特性、使用方法以及在实际应用中的优势,并通过丰富的代码示例帮助读者全面掌握这一重要工具。

CompletableFuture 概述

CompletableFuture实现了FutureCompletionStage接口,它不仅能够获取异步任务的结果,还能在任务完成时进行各种操作,比如执行回调函数、组合多个异步任务等。与传统的Future相比,CompletableFuture具有以下显著特点:

  • 异步操作的链式调用:可以通过链式调用的方式,对异步任务进行一系列的操作,无需手动管理线程和等待任务完成。
  • 自动回调机制:当异步任务完成时,会自动触发注册的回调函数,无需额外的轮询或等待操作。
  • 支持多个异步任务的组合:能够方便地组合多个异步任务,如并行执行、按顺序执行、等待所有任务完成或等待任一任务完成等。

CompletableFuture 基本用法

1. 创建 CompletableFuture

import java.util.concurrent.CompletableFuture;public class CompletableFutureExample {public static void main(String[] args) {// 创建一个异步任务,返回一个CompletableFuture对象CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 模拟异步任务的执行,这里使用Thread.sleep模拟耗时操作try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return "任务完成,返回结果";});// 获取异步任务的结果,这是一个阻塞操作try {String result = future.get();System.out.println("异步任务结果: " + result);} catch (Exception e) {e.printStackTrace();}}
}

在上述代码中,通过CompletableFuture.supplyAsync方法创建了一个异步任务,该方法接受一个Supplier接口的实现,返回一个CompletableFuture对象。在supplyAsync方法中,定义了异步任务的具体逻辑,这里通过Thread.sleep模拟了一个耗时 2 秒的操作,最后返回任务结果。通过future.get()方法获取异步任务的结果,该方法会阻塞当前线程,直到任务完成并返回结果。

2. 异步任务完成后的回调

import java.util.concurrent.CompletableFuture;public class CompletableFutureCallbackExample {public static void main(String[] args) {CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}return "任务完成";}).thenAccept(result -> {System.out.println("接收到任务结果: " + result);});// 主线程不能立即退出,否则异步任务可能无法执行try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}
}

在这段代码中,thenAccept方法用于注册一个回调函数,当异步任务完成并返回结果时,会自动调用该回调函数。thenAccept方法接受一个Consumer接口的实现,它会将异步任务的结果作为参数传递给回调函数。在示例中,回调函数只是简单地打印接收到的任务结果。

3. 处理异步任务的异常

import java.util.concurrent.CompletableFuture;public class CompletableFutureExceptionExample {public static void main(String[] args) {CompletableFuture.supplyAsync(() -> {if (Math.random() > 0.5) {throw new RuntimeException("任务执行出错");}return "任务完成";}).exceptionally(ex -> {System.out.println("捕获到异常: " + ex.getMessage());return "默认结果";}).thenAccept(result -> {System.out.println("最终结果: " + result);});try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}
}

exceptionally方法用于处理异步任务执行过程中抛出的异常。它接受一个Function接口的实现,当异步任务抛出异常时,会调用该函数,将异常作为参数传递进去,函数返回一个默认值,作为最终的结果。在示例中,通过Math.random()模拟了任务可能抛出异常的情况,当异常发生时,exceptionally方法捕获异常并返回一个默认结果,然后thenAccept方法处理最终结果。

CompletableFuture 组合异步任务

1. 多个异步任务并行执行并等待所有任务完成

import java.util.concurrent.CompletableFuture;public class CompletableFutureAllOfExample {public static void main(String[] args) {CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}return "任务1完成";});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return "任务2完成";});CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future1, future2);allOfFuture.join();try {System.out.println("任务1结果: " + future1.get());System.out.println("任务2结果: " + future2.get());} catch (Exception e) {e.printStackTrace();}}
}

CompletableFuture.allOf方法用于将多个CompletableFuture组合在一起,等待所有任务完成。allOf方法返回一个新的CompletableFuture<Void>,当所有传入的CompletableFuture都完成时,这个新的CompletableFuture也会完成。在示例中,创建了两个异步任务future1future2,然后使用allOf方法将它们组合起来,通过join方法等待所有任务完成,最后获取并打印每个任务的结果。

2. 多个异步任务并行执行并等待任一任务完成

import java.util.concurrent.CompletableFuture;public class CompletableFutureAnyOfExample {public static void main(String[] args) {CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return "任务1完成";});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}return "任务2完成";});CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(future1, future2);try {System.out.println("最先完成的任务结果: " + anyOfFuture.get());} catch (Exception e) {e.printStackTrace();}}
}

CompletableFuture.anyOf方法用于将多个CompletableFuture组合在一起,只要其中任一任务完成,这个新的CompletableFuture就会完成,并返回最先完成的任务的结果。在示例中,创建了两个异步任务future1future2,使用anyOf方法将它们组合,通过get方法获取最先完成的任务结果并打印。

结语

感谢您的阅读!如果您对 CompletableFuture 或其他并发编程话题有任何疑问或见解,欢迎继续探讨。

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

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

相关文章

排序算法--快速排序

快速排序是高效的排序算法&#xff0c;平均时间复杂度为 O(nlog⁡n)&#xff0c;适合大规模数据排序。 1.挖坑法 2左右指针法 3.前后指针法 // 交换两个元素的值 void swap(int* a, int* b) {int temp *a;*a *b;*b temp; }// 分区函数&#xff0c;返回分区点的索引 int par…

分享|LLM通过D-E-P-S完成长时间与多步骤的任务

《Describe, Explain, Plan and Select: Interactive Planning with Large Language Models Enables Open-World Multi-Task Agents&#xff1f; 描述、解释、计划和选择&#xff1a;使用大型语言模型进行交互式规划&#xff0c;实现开放世界的多任务代理 问题背景&#xff1a;…

chrome浏览器chromedriver下载

chromedriver 下载地址 https://googlechromelabs.github.io/chrome-for-testing/ 上面的链接有和当前发布的chrome浏览器版本相近的chromedriver 实际使用感受 chrome浏览器会自动更新&#xff0c;可以去下载最新的chromedriver使用&#xff0c;自动化中使用新的chromedr…

swagger使用指引

1.swagger介绍 在前后端分离开发中通常由后端程序员设计接口&#xff0c;完成后需要编写接口文档&#xff0c;最后将文档交给前端工程师&#xff0c;前端工程师参考文档进行开发。 可以通过一些工具快速生成接口文档 &#xff0c;本项目通过Swagger生成接口在线文档 。 什么…

一文速览DeepSeek-R1的本地部署——可联网、可实现本地知识库问答:包括671B满血版和各个蒸馏版的部署

前言 自从deepseek R1发布之后「详见《一文速览DeepSeek R1&#xff1a;如何通过纯RL训练大模型的推理能力以比肩甚至超越OpenAI o1(含Kimi K1.5的解读)》」&#xff0c;deepseek便爆火 爆火以后便应了“人红是非多”那句话&#xff0c;不但遭受各种大规模攻击&#xff0c;即便…

低通滤波算法的数学原理和C语言实现

目录 概述 1 原理介绍 1. 1 基本概念 1.2 一阶RC低通滤波器模型 2 C语言完整实现 2.1 滤波器结构体定义 2.2 初始化函数 2.3 滤波计算函数 3 应用示例 3.1 噪声信号滤波 3.2 输出效果对比 3.3 关键参数选择指南 4 性能优化技巧 4.1 定点数优化 4.2 抗溢出处理 …

自研有限元软件与ANSYS精度对比-Bar3D2Node三维杆单元模型-央视大裤衩实例

目录 1、“央视大裤衩”自研有限元软件求解 1.1、选择单元类型 1.2、导入“央视大裤衩”工程 1.3、节点坐标定义 1.4、单元连接关系、材料定义 1.5、约束定义 1.6、外载定义 1.7、矩阵求解 1.8、变形云图展示 1.9、节点位移 1.10、单元应力 1.11、节点支反力 2、“…

Hot100之堆

我们的PriorityQueue默认为最小堆&#xff0c;堆顶总是为最小 215数组中的第K个最大元素 题目 思路解析 暴力解法&#xff08;不符合时间复杂度&#xff09; 题目要求我们找到「数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素」。「数组排序后的第 k …

FinRobot:一个使用大型语言模型的金融应用开源AI代理平台

“FinRobot: An Open-Source AI Agent Platform for Financial Applications using Large Language Models” 论文地址&#xff1a;https://arxiv.org/pdf/2405.14767 Github地址&#xff1a;https://github.com/AI4Finance-Foundation/FinRobot 摘要 在金融领域与AI社区间&a…

算法题(57):找出字符串中第一个匹配项的下标

审题: 需要我们根据原串与模式串相比较并找到完全匹配时子串的第一个元素索引&#xff0c;若没有则返回-1 思路&#xff1a; 方法一&#xff1a;BF暴力算法 思路很简单&#xff0c;我们用p1表示原串的索引&#xff0c;p2表示模式串索引。遍历原串&#xff0c;每次遍历都匹配一次…

「全网最细 + 实战源码案例」设计模式——策略模式

核心思想 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;用于定义一系列算法或策略&#xff0c;将它们封装成独立的类&#xff0c;并使它们可以相互替换&#xff0c;而不影响客户端的代码&#xff0c;提高代码的可维护性和扩展性。 结构 …

linux 进程补充

环境变量 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪 里&#xff0c;但是照样可以链接成功&#…

排序算法--选择排序

选择排序虽然简单&#xff0c;但时间复杂度较高&#xff0c;适合小规模数据或教学演示。 // 选择排序函数 void selectionSort(int arr[], int n) {for (int i 0; i < n - 1; i) { // 外层循环控制当前最小值的存放位置int minIndex i; // 假设当前位置是最小值的索引// 内…

java求职学习day27

数据库连接池 &DBUtils 1.数据库连接池 1.1 连接池介绍 1) 什么是连接池 实际开发中 “ 获得连接 ” 或 “ 释放资源 ” 是非常消耗系统资源的两个过程&#xff0c;为了解决此类性能问题&#xff0c;通常情况我们 采用连接池技术&#xff0c;来共享连接 Connection 。…

接入DeepSeek大模型

接入DeepSeek 下载并安装Ollamachatbox 软件配置大模型 下载并安装Ollama 下载并安装Ollama&#xff0c; 使用参数ollama -v查看是否安装成功。 输入命令ollama list&#xff0c; 可以看到已经存在4个目录了。 输入命令ollama pull deepseek-r1:1.5b&#xff0c; 下载deepse…

AI大模型(二)基于Deepseek搭建本地可视化交互UI

AI大模型&#xff08;二&#xff09;基于Deepseek搭建本地可视化交互UI DeepSeek开源大模型在榜单上以黑马之姿横扫多项评测&#xff0c;其社区热度指数暴涨、一跃成为近期内影响力最高的话题&#xff0c;这个来自中国团队的模型向世界证明&#xff1a;让每个普通人都能拥有媲…

防火墙安全策略实验

一、实验拓扑图及实验要求 实验要求&#xff1a; 1、VLAN2属于办公区&#xff1b;VLAN 3属于生产区。 2、办公区PC在工作日时间&#xff08;周一至周五&#xff0c;早8到晚6)可以正常访问0A Server&#xff0c;其他时间不允许。 3、办公区可以在任意时刻访问web Server 4、生产…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】3.1 NumPy图像大小调整实战

3.1 NumPy图像大小调整实战 目录 #mermaid-svg-uDg4hyooC74c0r2r {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-uDg4hyooC74c0r2r .error-icon{fill:#552222;}#mermaid-svg-uDg4hyooC74c0r2r .error-text{fill:#5…

AI 编程工具—Cursor进阶使用 Agent模式

AI 编程工具—Cursor进阶使用 Agent模式 我们在使用Cursor 的是有,在Composer 模式下,提交的是有两种模式 Normal 模式,也就是默认的模式Agent 模式Agent 模式可以帮我们生成代码文件,执行程序,安装依赖,并且完成一些列的工作 这里有个点很重要就是在Agent 模式下,Cur…

在React中使用redux

一、首先安装两个插件 1.Redux Toolkit 2.react-redux 第一步&#xff1a;创建模块counterStore 第二步&#xff1a;在store的入口文件进行子模块的导入组合 第三步&#xff1a;在index.js中进行store的全局注入 第四步&#xff1a;在组件中进行使用 第五步&#xff1a;在组件中…