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实现了两个接口:Future 和 CompletionStage。
- 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,这种多元依赖可以通过allOf
或anyOf
方法来实现,区别是当需要多个依赖全部完成时使用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的异步化 项目描述 项目接口需要从下游多个接口获取数据,并且下游的网络不稳定还会涉及到循环调用…...

51单片机的时钟系统
1.简介 51内置的时钟系统可以用来计时,与主程序分割开来,在计时过程中不会终端主程序,还可以通过开启时钟中断来执行相应的操作。 2.单片机工作方式 单片机内部有两个十六位的定时器T0和T1。每个定时器有两种工作方式选择,分别…...
神经网络的问题总结
神经网络目前可以分为以下几类问题,每类问题都有其特点和不断取得的进展: 分类问题: 特点:在给定一组数据点的情况下,将它们分为不同的类别。进展:神经网络在图像分类、文本分类、音频分类等方面取得了显著…...
树莓派图像处理基础知识
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、基本函数1. cvtColor(src,tmp,COLOR_BGR2RGB);2.在OpenCV和Qt中,转换cv::Mat到QImage3.Canny(tmp,dst,30,255);4.dst matframe.clone();5.video…...
Kotlin中的Lambda表达式基本定义和使用
在Kotlin中,Lambda表达式是一种简洁的方式来定义匿名函数。Lambda表达式可以作为函数的实际参数或者返回值,使得函数成为高阶函数。本篇博客将介绍Lambda表达式的基本概念以及使用方法,并提供相关的示例代码。 Lambda表达式的基本概念 Lamb…...

递福巴士是不是骗局呢?
递福巴士的背景介绍 递福巴士是社区服务机构软件。递福巴士是一家提供公益服务的平台,为社区居民提供各种服务和支持的软件。多年来,递福巴士一直致力于社区服务和社会公益,积极推动社区的发展,改善社区居民的生活质量。 递福巴士…...
torch.Size([])与torch.Size([0])的区别
在PyTorch中,torch.Size([])和torch.Size([0])都表示一个空的维度(dimension)。然而,它们之间有微妙的区别。 torch.Size([]): 表示一个标量(scalar),即一个没有维度的张量。这个张量…...

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

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

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

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

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

Reparameterization trick(重参数化技巧)
“Reparameterization trick”(重参数化技巧)是一种在训练生成模型中处理随机性潜在变量的方法,特别常见于变分自动编码器(VAE)等模型中。这个技巧的目的是使模型可微分(differentiable)&#x…...
Kotlin中的可空类型
在 Kotlin 中,可空类型是一项重要的特性,它允许我们声明变量可以为空。在本篇博客中,我们将介绍 Kotlin 中的可空类型,并提供示例代码演示如何处理可空变量、使用安全调用操作符(?.)、Elvis 运算符&#x…...

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

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

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

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

从0开始在Vscode中搭建Vue2/3项目详细步骤
1.安装node.js:Node.js下载安装及环境配置教程【超详细】_nodejs下载_WHF__的博客-CSDN博客 node.js自带npm,无需单独安装。 验证: node -v npm -v 2.先简单创建一个空文件夹,vscode进入该文件夹,并打开终端。 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) 中创建多级目录或文件,可以使用鸿蒙的文件系统 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起源
🐍《Python 的诞生》:一段圣诞假期的奇妙冒险 📍时间:1989 年圣诞节 在荷兰阿姆斯特丹的一个寒冷冬夜,灯光昏黄、窗外飘着雪。一个程序员 Guido van Rossum 正窝在家里度假——没有会议、没有项目、没有 bug…...

Framework开发之IMS逻辑浅析1--关键线程及作用
关键线程:EventHub,InputReader,InputDispatcher EventHub: 由于Android继承Linux,Linux的思想是一切皆文件,而输入的类型不止一种(触碰,写字笔,键盘等),每种类型都对应一种驱动设备,而每个硬件驱动设备又对应Linux的一个目录文件…...
GitOps 核心思想 - 当 Git 成为唯一信源
GitOps 核心思想 - 当 Git 成为唯一信源 在我们之前的 CI/CD 系列中,我们构建了一条流水线:GitHub Actions 在代码测试和构建通过后,执行 kubectl apply 命令将变更推送 (Push) 到 Kubernetes 集群。这种模式非常普遍且有效,但当系统规模和团队复杂度增加时,它可能会遇到一…...
【Linux基础知识系列】第十一篇-Linux系统安全
Linux系统安全是指通过一系列技术和管理措施,保护Linux系统免受各种威胁和攻击,确保系统的完整性、可用性和机密性。随着网络攻击手段的多样化和复杂化,Linux系统安全成为了系统管理员和开发者必须面对的重要课题。本文将从用户认证、权限管理…...
MCP(Model Context Protocol)与提示词撰写
随着大模型(LLM)在复杂任务中的普及,如何让模型高效调用外部工具和数据成为关键挑战。传统函数调用(Function Calling)依赖开发者手动封装 API,而 MCP(Model Context Protocol) 通过…...
12.vite,webpack构建工具
😺😺 😺1.vite 介绍和对比 🏷️ Vite 是什么? 👉 Vite 是一个 前端构建工具 开发服务器, 可以帮你: • 开发阶段:秒开项目,改代码能瞬间热更新(…...

从以物换物到DeFi:交易的演变与Arbitrum的DeFi生态
交易的本质:从以物换物到现代金融 交易是人类社会经济活动的核心,是通过交换资源(如货物、服务或货币)满足各方需求的行为。其本质是价值交换,旨在实现资源的优化配置。交易的历史可以追溯到人类文明的起源࿰…...

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

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