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

completablefuture的使用

CompletableFuture使用详解

【Java异常】Variable used in lambda expression should be final or effectively final

CompletableFuture原理与实践-外卖商家端API的异步化

项目描述

项目接口需要从下游多个接口获取数据,并且下游的网络不稳定还会涉及到循环调用下游接口,导致该接口响应异常慢。

其实调用链路如图所示

在这里插入图片描述

cf1 ~ cf5 都需要调用下游接口,导致只能按照顺序,依次调用接口。其实可以将,例如cf1,cf2 拆分成两个异步请求,没必要cf2必须等待cf1请求完成才请求。

CompletableFuture 简介

之前使用的是同步模型。在同步调用的场景下,接口耗时长、性能差,接口响应时长T > T1+T2+T3+……+Tn。

利用 CompletableFuture 之后,使用的是异步模型,并行从下游获取数据。

Completable实现了两个接口:FutureCompletionStage

  • Future:表示异步计算结果
  • CompletionStage:表示异步执行过程中的一个步骤,这个步骤可能是由另外一个 CompletionStage触发的。

随着当前步骤的完成,也可能会触发其他一系列CompletionStage的执行。从而我们可以根据实际业务对这些步骤进行多样化的编排组合,CompletionStage接口正是定义了这样的能力,我们可以通过其提供的thenAppy、thenCompose等函数式编程方法来组合编排这些步骤。

使用教程

具体使用教程可以参考这边文章CompletableFuture原理与实践-外卖商家端API的异步化,描述的十分详细和生动。

项目应用

cf1,cf2由于没有任何依赖,可是需要返回值,故设计为

CompletableFuture<List<xxxDto>> cf1 = CompletableFuture.supplyAsync(() -> {//业务处理if (CollectionUtils.isEmpty(resp.getData())) {//其他线程抛出异常}return resp.getData();
}).exceptionally(ex -> {//主线程处理其他线程抛出的异常
});

cf3,cf5由于依赖 cf1, cf2 ,所以可以通过thenApply、thenAccept、thenCompose等方法来实现

但注意,返回数据类型必须相同。

CompletableFuture<xxxDto> cf3 = cf1.thenApply(result1 -> {//result1为cf1的结果//......return resp.getData();
});
CompletableFuture<xxxDto> cf5 = cf2.thenApply(result2 -> {//result2为cf2的结果//......return resp.getData();
});

cf4,依赖cf1,cf2 ,这种二元依赖可以通过thenCombine等回调来实现

CompletableFuture<String> cf4 = cf1.thenCombine(cf2, (result1, result2) -> {//result1和result2分别为cf1和cf2的结果return "result4";
});

由于cf6依赖cf3,cf4,cf5,这种多元依赖可以通过allOfanyOf方法来实现,区别是当需要多个依赖全部完成时使用allOf,当多个依赖中的任意一个完成即可时使用anyOf

CompletableFuture<Void> cf6 = CompletableFuture.allOf(cf3, cf4, cf5);
CompletableFuture<String> result = cf6.thenApply(v -> {//这里的join并不会阻塞,因为传给thenApply的函数是在CF3、CF4、CF5全部完成时,才会执行 。result3 = cf3.join();result4 = cf4.join();result5 = cf5.join();//根据result3、result4、result5组装最终result;return "result";
});

需注意,如果cfx里用到方法的局部变量需要设置为final,避免completablefuture在使用该变量的时候被修改。

设计思想

按照类似 “观察者模式” 的设计思想

异步化收益

接口响应从 TP99=3s左右,提升到2s左右

相关文章:

completablefuture的使用

CompletableFuture使用详解 【Java异常】Variable used in lambda expression should be final or effectively final CompletableFuture原理与实践-外卖商家端API的异步化 项目描述 项目接口需要从下游多个接口获取数据&#xff0c;并且下游的网络不稳定还会涉及到循环调用…...

51单片机的时钟系统

1.简介 51内置的时钟系统可以用来计时&#xff0c;与主程序分割开来&#xff0c;在计时过程中不会终端主程序&#xff0c;还可以通过开启时钟中断来执行相应的操作。 2.单片机工作方式 单片机内部有两个十六位的定时器T0和T1。每个定时器有两种工作方式选择&#xff0c;分别…...

神经网络的问题总结

神经网络目前可以分为以下几类问题&#xff0c;每类问题都有其特点和不断取得的进展&#xff1a; 分类问题&#xff1a; 特点&#xff1a;在给定一组数据点的情况下&#xff0c;将它们分为不同的类别。进展&#xff1a;神经网络在图像分类、文本分类、音频分类等方面取得了显著…...

树莓派图像处理基础知识

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、基本函数1. cvtColor(src,tmp,COLOR_BGR2RGB);2.在OpenCV和Qt中&#xff0c;转换cv::Mat到QImage3.Canny(tmp,dst,30,255);4.dst matframe.clone();5.video…...

Kotlin中的Lambda表达式基本定义和使用

在Kotlin中&#xff0c;Lambda表达式是一种简洁的方式来定义匿名函数。Lambda表达式可以作为函数的实际参数或者返回值&#xff0c;使得函数成为高阶函数。本篇博客将介绍Lambda表达式的基本概念以及使用方法&#xff0c;并提供相关的示例代码。 Lambda表达式的基本概念 Lamb…...

递福巴士是不是骗局呢?

递福巴士的背景介绍 递福巴士是社区服务机构软件。递福巴士是一家提供公益服务的平台&#xff0c;为社区居民提供各种服务和支持的软件。多年来&#xff0c;递福巴士一直致力于社区服务和社会公益&#xff0c;积极推动社区的发展&#xff0c;改善社区居民的生活质量。 递福巴士…...

torch.Size([])与torch.Size([0])的区别

在PyTorch中&#xff0c;torch.Size([])和torch.Size([0])都表示一个空的维度&#xff08;dimension&#xff09;。然而&#xff0c;它们之间有微妙的区别。 torch.Size([])&#xff1a; 表示一个标量&#xff08;scalar&#xff09;&#xff0c;即一个没有维度的张量。这个张量…...

DP基础相关笔记

基础 DP LIS LIS&#xff08;Longest Increasing Subsequence&#xff09;&#xff0c;顾名思义&#xff0c;就是最长上升子序列问题。 在这里我们要区分一下子串和子序列的区别&#xff0c;很简单&#xff0c;子串连续&#xff0c;子序列可以不连续。然而就在几小时之前本蒟…...

配置公网和私网用户通过非公网口的IP地址访问内部服务器和Internet示例

组网需求 如配置公网和私网用户通过非公网口的IP地址访问内部服务器和Internet示例所示&#xff0c;某小型企业内网部署了一台路由器、一台FTP服务器和一台Web服务器。路由器作为接入网关&#xff0c;为下挂的内网用户提供上网服务&#xff0c;主要包括浏览网页、使用即时通信…...

相机镜头选择与机器视觉控制

相机镜头选择与机器视觉控制 在机器视觉领域&#xff0c;除了图像处理和算法&#xff0c;还需要关注硬件方面的选型和控制。相机镜头的选择是其中重要的一部分&#xff0c;需要考虑像素大小、镜头焦距等因素以满足项目需求。此外&#xff0c;编程技能也包括相机的调用和使用&a…...

Git 为文件添加执行权限

背景 当你是一台Linux&#xff0c;想要给文件加权限很简单&#xff0c;只需要执行以下命令 chmod x filename就可以给文件添加执行权限&#xff0c;但是如果你是Windows那就很麻烦了 解决方案 假设这里有一个名为 file.sh 的文件&#xff0c;内容如下&#xff1a; #!/bin/…...

问题记录:GPU显卡提高后,代码总体运行效率没有提高

问题&#xff1a;GPU显卡提高后&#xff0c;代码总体运行效率没有提高 原先显卡NIVIDA T400换成NVIDIA RTX A4000&#xff0c;CUDA核心&#xff08;物理GPU线程单位&#xff09;从三百多提升到了六千多&#xff0c;但是程序总体运行的时间没有变化。 原因分析 显卡没用上或者…...

Reparameterization trick(重参数化技巧)

“Reparameterization trick”&#xff08;重参数化技巧&#xff09;是一种在训练生成模型中处理随机性潜在变量的方法&#xff0c;特别常见于变分自动编码器&#xff08;VAE&#xff09;等模型中。这个技巧的目的是使模型可微分&#xff08;differentiable&#xff09;&#x…...

Kotlin中的可空类型

在 Kotlin 中&#xff0c;可空类型是一项重要的特性&#xff0c;它允许我们声明变量可以为空。在本篇博客中&#xff0c;我们将介绍 Kotlin 中的可空类型&#xff0c;并提供示例代码演示如何处理可空变量、使用安全调用操作符&#xff08;?.&#xff09;、Elvis 运算符&#x…...

数学建模——最大流问题(配合例子说明)

目录 一、最大流有关的概念 例1 1、容量网络的定义 2、符号设置 3、建立模型 3.1 每条边的容量限制 3.2 平衡条件 3.3 网络的总流量 4、网络最大流数学模型 5、计算 二、最小费用流 例2 【符号说明】 【建立模型】 &#xff08;1&#xff09;各条边的流量限制 &a…...

AAOS CarMediaService 服务框架

文章目录 前言MediaSessionCarMediaService作用是什么&#xff1f;提供了哪些接口&#xff1f;如何使用&#xff1f;CarMediaService的实现总结 前言 CarMediaService 是AAOS中统一管理媒体播放控制、信息显示和用户交互等功能的服务。这一服务依赖于android MediaSession框架…...

gRPC之gRPC转换HTTP

1、gRPC转换HTTP 我们通常把RPC用作内部通信&#xff0c;而使用Restful Api进行外部通信。为了避免写两套应用&#xff0c;我们使用grpc- gateway 把gRPC转成HTTP。服务接收到HTTP请求后&#xff0c;grpc-gateway把它转成gRPC进行处理&#xff0c;然后以JSON 形式返回数据。…...

【十四】记一次MySQL宕机恢复过程,MySQL INNODB 损坏恢复

记一次MySQL宕机恢复过程 简介&#xff1a;一个业务数据库疏于运维管理&#xff0c;突然在今天崩溃宕机了&#xff0c;真是让人抓狂&#xff0c;上面也不知道积累了多久的数据&#xff0c;平时也没有定期做好备份&#xff0c;这下岂不是瞎了啊&#xff0c;经过不断的收集信息和…...

从0开始在Vscode中搭建Vue2/3项目详细步骤

1.安装node.js:Node.js下载安装及环境配置教程【超详细】_nodejs下载_WHF__的博客-CSDN博客 node.js自带npm&#xff0c;无需单独安装。 验证&#xff1a; node -v npm -v 2.先简单创建一个空文件夹&#xff0c;vscode进入该文件夹&#xff0c;并打开终端。 3.安装cnpm&…...

JavaScript ES6类的定义与继承

文章目录 一、class方式定义类1.认识class定义类2.类和构造函数的异同3.类的构造函数4.类的实例方法5.类的访问器方法6.类的静态方法 二、继承1.extends实现继承2.super关键字3.继承内置类4.类的混入mixin 三、ES6转ES51.class转换2.extends转换 四、多态 一、class方式定义类 …...

【鸿蒙在 ETS (Extendable TypeScript) 中创建多级目录或文件,可以使用鸿蒙的文件系统 API】

鸿蒙在 ETS (Extendable TypeScript) 中创建多级目录或文件&#xff0c;可以使用鸿蒙的文件系统 API。 // 导入需要的模块 import fs from ohos.file.fs;const TAG"Index" Entry Component struct Index {State message: string Hello World;build() {Row() {Colum…...

Python学习(7) ----- Python起源

&#x1f40d;《Python 的诞生》&#xff1a;一段圣诞假期的奇妙冒险 &#x1f4cd;时间&#xff1a;1989 年圣诞节 在荷兰阿姆斯特丹的一个寒冷冬夜&#xff0c;灯光昏黄、窗外飘着雪。一个程序员 Guido van Rossum 正窝在家里度假——没有会议、没有项目、没有 bug&#xf…...

Framework开发之IMS逻辑浅析1--关键线程及作用

关键线程:EventHub,InputReader,InputDispatcher EventHub: 由于Android继承Linux,Linux的思想是一切皆文件,而输入的类型不止一种(触碰&#xff0c;写字笔&#xff0c;键盘等)&#xff0c;每种类型都对应一种驱动设备&#xff0c;而每个硬件驱动设备又对应Linux的一个目录文件…...

GitOps 核心思想 - 当 Git 成为唯一信源

GitOps 核心思想 - 当 Git 成为唯一信源 在我们之前的 CI/CD 系列中,我们构建了一条流水线:GitHub Actions 在代码测试和构建通过后,执行 kubectl apply 命令将变更推送 (Push) 到 Kubernetes 集群。这种模式非常普遍且有效,但当系统规模和团队复杂度增加时,它可能会遇到一…...

【Linux基础知识系列】第十一篇-Linux系统安全

Linux系统安全是指通过一系列技术和管理措施&#xff0c;保护Linux系统免受各种威胁和攻击&#xff0c;确保系统的完整性、可用性和机密性。随着网络攻击手段的多样化和复杂化&#xff0c;Linux系统安全成为了系统管理员和开发者必须面对的重要课题。本文将从用户认证、权限管理…...

MCP(Model Context Protocol)与提示词撰写

随着大模型&#xff08;LLM&#xff09;在复杂任务中的普及&#xff0c;如何让模型高效调用外部工具和数据成为关键挑战。传统函数调用&#xff08;Function Calling&#xff09;依赖开发者手动封装 API&#xff0c;而 MCP&#xff08;Model Context Protocol&#xff09; 通过…...

12.vite,webpack构建工具

&#x1f63a;&#x1f63a; &#x1f63a;1.vite 介绍和对比 &#x1f3f7;️ Vite 是什么&#xff1f; &#x1f449; Vite 是一个 前端构建工具 开发服务器&#xff0c; 可以帮你&#xff1a; • 开发阶段&#xff1a;秒开项目&#xff0c;改代码能瞬间热更新&#xff08;…...

从以物换物到DeFi:交易的演变与Arbitrum的DeFi生态

交易的本质&#xff1a;从以物换物到现代金融 交易是人类社会经济活动的核心&#xff0c;是通过交换资源&#xff08;如货物、服务或货币&#xff09;满足各方需求的行为。其本质是价值交换&#xff0c;旨在实现资源的优化配置。交易的历史可以追溯到人类文明的起源&#xff0…...

⚡️ Linux Docker 基本命令参数详解

&#x1f433; Linux Docker 基本命令参数详解 &#x1f4d8; 1. Docker 简介 Docker 是一个开源的容器化平台&#xff0c;它通过将应用及其依赖打包到一个轻量级、可移植的容器中&#xff0c;从而实现跨平台运行。Docker 采用 C/S 架构&#xff0c;服务端称为 Docker Daemon&a…...

CAD实体对象智能识别

CAD实体对象智能识别 概述 实体对象智能识别能够在CAD图纸中智能识别和匹配相似的实体对象。该系统采用模式匹配算法&#xff0c;支持几何变换&#xff08;缩放、旋转&#xff09;&#xff0c;并提供了丰富的配置选项和可视化界面。 系统提供两种主要的识别方式&#xff1a;…...