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

深入理解Java CompletableFuture并发编程模型

摘要:本文将介绍Java中的CompletableFuture类,探讨其在并发编程中的应用。我们将详细讨论CompletableFuture的特性、常见用法和最佳实践,帮助开发人员更好地利用这个强大的工具进行异步编程。

1. 什么是CompletableFuture?

CompletableFuture是Java 8中引入的一个类,它提供了一种方便、灵活和高效的方法来处理并发任务。CompletableFuture基于Future和Promise的概念,它可以表示一个异步计算的结果,并且可以通过回调机制或者组合其他CompletableFuture实例来实现复杂的异步操作。

2. CompletableFuture的特性

  • 异步执行:CompletableFuture允许我们将任务提交到线程池中异步执行,避免阻塞主线程。
  • 链式操作:通过thenApply、thenAccept、thenRun等方法,我们可以将多个CompletableFuture串联起来形成一个操作链,以便在每个任务完成后执行下一步操作。
  • 组合操作:CompletableFuture提供了多种组合操作,如allOf、anyOf等,用于处理多个CompletableFuture实例的结果。
  • 异常处理:可以使用exceptionally或handle方法捕获并处理异常情况,确保任务的稳定运行。
  • 超时控制:可以使用completeOnTimeout或completeOnCancel方法设置任务的超时时间,并在超时后执行相应的操作。

3. CompletableFuture的常见用法

3.1 异步执行任务

使用CompletableFuture.runAsync和CompletableFuture.supplyAsync方法可以将任务提交到线程池中异步执行:

CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {// 异步执行的任务
});CompletableFuture<T> future = CompletableFuture.supplyAsync(() -> {// 异步执行的任务,返回结果类型为T
});

3.2 链式操作

通过thenApply、thenAccept、thenRun等方法,我们可以将多个CompletableFuture实例串联起来形成一个操作链,以便在每个任务完成后执行下一步操作:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello").thenApply(s -> s + " World").thenApply(String::toUpperCase);future.thenAccept(System.out::println);  // 打印结果:HELLO WORLD

3.3 组合操作

使用allOf、anyOf等方法可以处理多个CompletableFuture实例的结果:

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");CompletableFuture.allOf(future1, future2).thenRun(() -> {String result1 = future1.join();String result2 = future2.join();System.out.println(result1 + " " + result2);  // 打印结果:Hello World});

3.4 异常处理

使用exceptionally或handle方法可以捕获并处理异常情况:

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {// 可能会抛出异常的任务throw new RuntimeException("Something went wrong");
});future.exceptionally(ex -> {System.out.println("Exception occurred: " + ex);return 0;  // 指定默认值
});future.handle((result, ex) -> {if (ex != null) {System.out.println("Exception occurred: " + ex);return 0;} else {return result;}
});

3.5 超时控制

使用completeOnTimeout或completeOnCancel方法可以设置任务的超时时间,并在超时后执行相应的操作:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {// 异步执行的任务return "Result";
});CompletableFuture<String> timeoutFuture = future.completeOnTimeout("Timeout", 1, TimeUnit.SECONDS);timeoutFuture.thenAccept(System.out::println);  // 如果任务在1秒内未完成,打印结果:Timeout

4. 完整示例

以下是一个完整的示例代码,展示了CompletableFuture在并发编程中的用法:

import java.util.concurrent.CompletableFuture;public class CompletableFutureExample {public static void main(String[] args) {CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello").thenApply(s -> s + " World").thenApply(String::toUpperCase);future.thenAccept(System.out::println);  // 打印结果:HELLO WORLD}
}

5. 结论

CompletableFuture是Java中强大的并发编程工具,通过异步执行、链式操作和组合等特性,可以极大地简化异步任务的处理。本文介绍了CompletableFuture的基本特性和常见用法,并提供了一些最佳实践。掌握CompletableFuture的使用,将有助于开发人员编写高效、可靠和响应式的并发代码。

相关文章:

深入理解Java CompletableFuture并发编程模型

摘要&#xff1a;本文将介绍Java中的CompletableFuture类&#xff0c;探讨其在并发编程中的应用。我们将详细讨论CompletableFuture的特性、常见用法和最佳实践&#xff0c;帮助开发人员更好地利用这个强大的工具进行异步编程。 1. 什么是CompletableFuture&#xff1f; Compl…...

TensorFlow手动加载数据集(以mnist为例)

在进行Mnist手写识别的项目中&#xff0c;出现了Mnist数据集下载出错的问题&#xff0c;报出以下错误&#xff1a; Exception: URL fetch failure on https://s3.amazonaws.com/img-datasets/mnist.npz: None – [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主…...

C++项目实战——基于多设计模式下的同步异步日志系统(总集篇)

文章目录 专栏导读项目介绍开发环境核心技术环境搭建日志系统介绍1.为什么需要日志系统2.日志系统技术实现2.1同步写日志2.2异步写日志 前置知识补充不定参函数C风格不定参函数不定参宏函数设计模式六大原则单例模式饿汉模式懒汉模式 工厂模式简单工厂模式工厂方法模式抽象工厂…...

杨辉三角按列求和

假设求杨辉三角这一列 我们考虑这个格子&#xff1a; 然后对其不断展开 综上&#xff1a; ∑ i 0 n ( i k ) ( n 1 k 1 ) \sum_{i0}^n\binom i k\binom {n1}{k1} i0∑n​(ki​)(k1n1​) ∑ i l r ( i k ) ( r 1 k 1 ) − ( l k 1 ) \sum_{il}^r\binom i k\binom{r1}{k…...

C复习-语句

参考&#xff1a; 里科《C和指针》 语句 C没有bool&#xff0c;是用整型代替的。因此if(expression)中&#xff0c;expression只要是可以产生整型结果即可&#xff0c;且0表示假&#xff0c;非0表示真。 如果有只靠缩进没有{}的else语句&#xff0c;会自动匹配离它最近的、不…...

[Python进阶] 操纵键盘:PyAutoGUI

6.5 操纵键盘&#xff1a;PyAutoGUI 6.5.1 keyDown、keyUp 按下或弹起某个按键。在按下时不会释放。 参数: key(str): 要按下的键。有效的名称列在KEYBOARD_KEYS。 logScreenshot&#xff1a;是否要截图并保存在当前文件夹下。 import pyautoguipyautogui.keyDown(f) # 模拟…...

jdbc快速开始

文章目录 快速开始参考文献 jdbc 就是使用java语言操作关系型数据库的一套api jdbc本质&#xff1a; 官方(sun公司)定义的一套操作所有关系型数据库的规则&#xff0c;就是接口各个数据库厂商去实现这套接口&#xff0c;提供数据库驱动jar包我们可以使用这套接口编程&#xff…...

C语言中static关键字用法

C语言中static关键字用法 2021年7月28日席锦 static关键字在c语言中比较常用&#xff0c;使用恰当能够大大提高程序的模块化特性&#xff0c;有利于扩展和维护。但是对于c语言初学者&#xff0c;static由于使用灵活&#xff0c;并不容易掌握。 变量 1.局部变量 普通局部变量是再…...

STM32-LCD液晶显示

LCD液晶显示 针对野火指南者配套资料&#xff1a;3.2寸 LCD电阻屏&#xff0c;屏幕里自带ILI9341液晶控制器芯片&#xff0c;该控制器芯片中存在GRAM&#xff08;即显存&#xff09;。该液晶控制器使用8080接口与单片机通讯&#xff0c;液晶面板引出来的FPC信号线为8080接口&am…...

GraphQL 查询:一个全面指南

GraphQL GraphQL 是一种 API 查询语言和运行时&#xff0c;用于使用现有数据完成这些查询。它为您的 API 中的数据提供了完整且易于理解的描述&#xff0c;让客户能够准确地询问他们需要什么&#xff0c;更容易随着时间的推移发展 API&#xff0c;并启用强大的开发人员工具。 …...

快速自动化处理JavaScript渲染页面的方法

目录 一、使用无头浏览器 二、使用JavaScript渲染引擎 三、使用前端框架工具 随着互联网技术的不断发展&#xff0c;JavaScript已经成为Web开发中不可或缺的一部分。然而&#xff0c;在自动化处理JavaScript渲染页面方面&#xff0c;却常常让开发者感到头疼。本文将介绍一些快…...

[计算机提升] 系统及用户操作

1.4 系统及用户操作 1.4.1 系统操作 1.4.1.1 开机、关机、重启 在Windows系统中&#xff0c;开机&#xff08;Power On&#xff09;&#xff0c;关机&#xff08;Shutdown&#xff09;和重启&#xff08;Restart&#xff09;是指计算机的不同电源控制操作。 开机&#xff1a;…...

Linux篇 四、Linux修改用户名

Linux系列文章目录 一、香橙派Zero2设置开机连接wifi 二、香橙派Zero2获取Linux SDK源码 三、香橙派Zero2搭建Qt环境 文章目录 Linux系列文章目录前言一、更改用户名准备二、修改用户名总结 前言 想要把Ubuntu的普通用户名修改成自己想要的 一、更改用户名准备 LubanCat 镜像…...

【Element-plus】如何让滚动条永远在最底部(支持在线演示)

如何让滚动条永远在最底部 一、适用场景二、实现思路三、效果图四、在线演示五、完整代码 一、适用场景 在某些场景下&#xff0c;你可能希望滚动条保持在最底部&#xff0c;以确保用户始终看到最新的内容或信息。如&#xff1a;在实时聊天应用程序中&#xff0c;当新消息到达…...

解决方案-LBS用户位置Redis-GEO附近人/店铺

附近人 windows安装附近人列表功能mysqlredis GEO CNNVD-201511-230 未授权访问python 多线程 redis大端模式与小端模式IP地址的不同表现形式1.字符串表现形式2. 整数表现形式3.大小端模式下的IP地址 0x01 进入python正题Python的socket库1.socket.socket(family,type)2.socket…...

springboot+html实现简单注册登录

前端&#xff1a; register.html <!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>register</title><link rel"stylesheet" type"text/css" href"/css/style.css&…...

ESP32网络开发实例-Web控制8路继电器

Web控制8路继电器 文章目录 Web控制8路继电器1、继器器介绍2、软件准备3、硬件准备4、代码实现4.1 单路继电器控制灯泡4.2 Web控制8路继电器将继电器与 ESP32 一起使用是远程控制交流家用电器的好方法。 本文介绍如何使用 ESP32 控制继电器模块。 我们将了解继电器模块的工作原…...

Flutter ☞ 变量

在Flutter中&#xff0c;变量分为两种类型 弱类型强类型 弱类型 var 如果没有初始值&#xff0c;可以变成任何类型 var a; // var a ; // 一旦赋值&#xff0c;就确定类型&#xff0c;不能随意改动 a abc; a 123; a true; a {key: 123}; a [abc];print(a)Object 动…...

冲刺十五届蓝桥杯P0006平面切分

文章目录 题目思路代码总结 题目 平面切分 思路 这道题是一个思维题把&#xff0c;之前没有接触过平面几何的知识&#xff0c;做起来感觉还是比较难的&#xff0c;用到的set集合和自己创建一个类 首先我们知道&#xff0c;一根直线A是可以将平面切分成两块的&#xff0c;如…...

mac电脑文献管理 EndNote 21最新 for Mac

EndNote 21 Mac版不仅能够快速有效的的帮助用户管理自己的文献&#xff0c;而且还可以用来创建个人参考文献库&#xff0c;添加各种文本&#xff0c;图像&#xff0c;连接&#xff0c;表格等等内容&#xff01; - 搜索数百个在线资源以获取参考和PDF - 只需点击一下即可查找参…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...