CompletableFuture使用详解
一、 CompletableFuture介绍
平时多线程开发一般就是使用Runnable,Callable,Thread,FutureTask,ThreadPoolExecutor这些内容和并发编程息息相关。相对来对来说成本都不高,多多使用是可以熟悉这些内容。这些内容组合在一起去解决一些并发编程的问题时,很多时候没有办法很方便的去完成异步编程的操作。
Thread + Runnable:执行异步任务,但是没有返回结果
Thread + Callable + FutureTask:完整一个可以有返回结果的异步任务
- 获取返回结果,如果基于get方法获取,线程需要挂起在WaitNode里
- 获取返回结果,也可以基于isDone判断任务的状态,但是这里需要不断轮询
上述的方式都是有一定的局限性的。
CompletableFuture就是帮你处理这些任务之间的逻辑关系,编排好任务的执行方式后,任务会按照规划好的方式一步一步执行,不需要让业务线程去频繁的等待。
比如说任务A,任务B,还有任务C。其中任务B还有任务C执行的前提是任务A先完成,再执行任务B和任务C。
CompletionStage接口定义了任务编排的方法,执行某一阶段,可以向下执行后续阶段。异步执行的,默认线程池是ForkJoinPool.commonPool(),但为了业务之间互不影响,且便于定位问题,强烈推荐使用自定义线程池。
二、 应用
CompletableFuture应用还是需要一内内的成本的。
首先对CompletableFuture提供的函数式编程中三个函数有一个掌握
1. Supplier<U> // 生产者,没有入参,有返回结果
2. Consumer<T> // 消费者,有入参,但是没有返回结果
3. Function<T,U>// 函数,有入参,又有返回结果
2.1 功能
依赖关系
thenApply():把前面任务的执行结果,交给后面的Function
thenCompose():用来连接两个有依赖关系的任务,结果由第二个任务返回
and集合关系
thenCombine():合并任务,有返回值
thenAccepetBoth():两个任务执行完成后,将结果交给thenAccepetBoth处理,无返回值
runAfterBoth():两个任务都执行完成后,执行下一步操作(Runnable类型任务)
or聚合关系
applyToEither():两个任务哪个执行的快,就使用哪一个结果,有返回值
acceptEither():两个任务哪个执行的快,就消费哪一个结果,无返回值
runAfterEither():任意一个任务执行完成,进行下一步操作(Runnable类型任务)
并行执行
allOf():当所有给定的 CompletableFuture 完成时,返回一个新的 CompletableFuture
anyOf():当任何一个给定的CompletablFuture完成时,返回一个新的CompletableFuture
结果处理
whenComplete:当任务完成时,将使用结果(或 null)和此阶段的异常(或 null如果没有)执行给定操作
exceptionally:返回一个新的CompletableFuture,当前面的CompletableFuture完成时,它也完成,当它异常完成时,给定函数的异常触发这个CompletableFuture的完成
2.2 supplyAsync
CompletableFuture如果不提供线程池的话,默认使用的ForkJoinPool,而ForkJoinPool内部是守护线程,如果main线程结束了,守护线程会跟着一起结束。
public static void main(String[] args) {// 生产者,可以指定返回结果CompletableFuture<String> firstTask = CompletableFuture.supplyAsync(() -> {System.out.println("异步任务开始执行");System.out.println("异步任务执行结束");return "返回结果";});String result1 = firstTask.join();String result2 = null;try {result2 = firstTask.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}System.out.println(result1 + "," + result2);
}
2.3 runAsync
当前方式既不会接收参数,也不会返回任何结果,非常基础的任务编排方式
public static void main(String[] args) throws IOException {CompletableFuture.runAsync(() -> {System.out.println("任务go");System.out.println("任务done");});System.in.read();
}
2.4 thenApply,thenApplyAsync(自定义线程池)
有任务A,还有任务B。
任务B需要在任务A执行完毕后再执行。
而且任务B需要任务A的返回结果。
任务B自身也有返回结果。
thenApply可以拼接异步任务,前置任务处理完之后,将返回结果交给后置任务,然后后置任务再执行
thenApply提供了带有Async的方法,可以指定每个任务使用的具体线程池。
thenApply:
public static void main(String[] args) {CompletableFuture<String> taskA = CompletableFuture.supplyAsync(() -> {String id = UUID.randomUUID().toString();System.out.println("执行任务A:" + id);return id;});CompletableFuture<String> taskB = taskA.thenApply(result -> {System.out.println("任务B获取到任务A结果:" + result);result = result.replace("-", "");return result;});System.out.println("main线程拿到结果:" + taskB.join());
}
thenApplyAsync:
public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(10);CompletableFuture<String> taskB = CompletableFuture.supplyAsync(() -> {String id = UUID.randomUUID().toString();System.out.println("执行任务A:" + id + "," + Thread.currentThread().getName());return id;}).thenApplyAsync(result -> {System.out.println("任务B获取到任务A结果:" + result + "," + Thread.currentThread().getName());result = result.replace("-", "");return result;},executor);System.out.println("main线程拿到结果:" + taskB.join());
}
带Async的都是自定义线程池传参
2.5 thenAccept,thenAcceptAsync(自定义线程池)
套路和thenApply一样,都是任务A和任务B的拼接
前置任务需要有返回结果,后置任务会接收前置任务的结果,返回后置任务,没有返回值
public static void main(String[] args) throws IOException {CompletableFuture.supplyAsync(() -> {System.out.println("任务A");return "abcdefg";}).thenAccept(result -> {System.out.println("任务b,拿到结果处理:" + result);});System.in.read();
}
2.6 thenRun,thenRunAsync(自定义线程池)
套路和thenApply,thenAccept一样,都是任务A和任务B的拼接
前置任务没有返回结果,后置任务不接收前置任务结果,后置任务也没有返回结果。
public static void main(String[] args) throws IOException {CompletableFuture.runAsync(() -> {System.out.println("任务A!!");}).thenRun(() -> {System.out.println("任务B!!");});System.in.read();
}
2.7 thenCombine,thenAcceptBoth,runAfterBoth
比如有任务A,任务B,任务C。任务A和任务B并行执行,等到任务A和任务B全部执行完毕后,再执行任务C。
2.7.1 thenCombine
当前方式当前方式前置任务需要有返回结果,后置任务接收前置任务的结果,有返回值
public static void main(String[] args) {CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {System.out.println("任务A执行");return 10;}).thenCombine(CompletableFuture.supplyAsync(() -> {System.out.println("任务B执行");return 10;}), (r1, r2) -> {System.out.println("任务C执行");return r1 + r2;});System.out.println("任务C结果=" + future.join());}
2.7.2 thenAcceptBoth
当前方式前置任务需要有返回结果,后置任务接收前置任务的结果,没有返回值
public static void main(String[] args) {CompletableFuture.supplyAsync(() -> {System.out.println("任务A执行");return 10;}).thenAcceptBoth(CompletableFuture.supplyAsync(() -> {System.out.println("任务B执行");return 10;}), (r1, r2) -> {System.out.println("任务C执行");int r = r2 + r1;System.out.println("任务C结果=" + r);});}
2.7.3 runAfterBoth
当前方式前置任务不需要有返回结果,后置任务不会接收前置任务的结果,没有返回值
public static void main(String[] args) {CompletableFuture.supplyAsync(() -> {System.out.println("任务A执行");return 10;}).runAfterBoth(CompletableFuture.supplyAsync(() -> {System.out.println("任务B执行");return 10;}), () -> {System.out.println("任务C执行");});}
2.8 applyToEither,acceptEither,runAfterEither
这三个方法:比如有任务A,任务B,任务C。任务A和任务B并行执行,只要任务A或者任务B执行完毕,开始执行任务C
applyToEither:可以接收结果并且返回结果
acceptEither:可以接收结果没有返回结果
runAfterEither:不接收结果也没返回结果
三个方法拼接任务的方式都是一样的
applyToEither:只演示一个其它套路一样
public static void main(String[] args) throws IOException {CompletableFuture<Integer> taskC = CompletableFuture.supplyAsync(() -> {System.out.println("任务A");return 78;}).applyToEither(CompletableFuture.supplyAsync(() -> {System.out.println("任务B");return 66;}), resultFirst -> {System.out.println("任务C");return resultFirst;});System.out.println(taskC.join());System.in.read();
}
2.9 exceptionally,thenCompose,handle
exceptionally:
这个也是拼接任务的方式,但是只有前面业务执行时出现异常了,才会执行当前方法来处理
只有异常出现时,CompletableFuture的编排任务没有处理完时,才会触发。
拿不到任务结果。
whenComplete,handle:
这两个也是异常处理的套路,可以根据方法描述发现,他的功能方向比exceptionally要更加丰富
whenComplete可以拿到返回结果同时也可以拿到出现的异常信息,但是whenComplete本身是Consumer不能返回结果。无法帮你捕获异常,但是可以拿到异常返回的结果。
handle可以拿到返回结果同时也可以拿到出现的异常信息,并且也可以指定返回托底数据。可以捕获异常的,异常不会抛出去。
public static void main(String[] args) throws IOException {CompletableFuture<Integer> taskC = CompletableFuture.supplyAsync(() -> {System.out.println("任务A");
// int i = 1 / 0;return 78;}).applyToEither(CompletableFuture.supplyAsync(() -> {System.out.println("任务B");return 66;}), resultFirst -> {System.out.println("任务C");return resultFirst;}).handle((r,ex) -> {System.out.println("handle:" + r);System.out.println("handle:" + ex);return -1;});/*.exceptionally(ex -> {System.out.println("exceptionally:" + ex);return -1;});*//*.whenComplete((r,ex) -> {System.out.println("whenComplete:" + r);System.out.println("whenComplete:" + ex);});*/System.out.println(taskC.join());System.in.read();
}
2.10 allOf,anyOf
allOf:
allOf的方式是让内部编写多个CompletableFuture的任务,多个任务都执行完后,才会继续执行你后续拼接的任务
allOf返回的CompletableFuture是Void,没有返回结果
public static void main(String[] args) throws IOException {CompletableFuture.allOf(CompletableFuture.runAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("任务A");}),CompletableFuture.runAsync(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("任务B");}),CompletableFuture.runAsync(() -> {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("任务C");})).thenRun(() -> {System.out.println("任务D");});System.in.read();
}
anyOf:
anyOf是基于多个CompletableFuture的任务,只要有一个任务执行完毕就继续执行后续,最先执行完的任务做作为返回结果的入参
public static void main(String[] args) throws IOException {CompletableFuture.anyOf(CompletableFuture.supplyAsync(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("任务A");return "A";}),CompletableFuture.supplyAsync(() -> {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("任务B");return "B";}),CompletableFuture.supplyAsync(() -> {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("任务C");return "C";})).thenAccept(r -> {System.out.println("任务D执行," + r + "先执行完毕的");});System.in.read();
}
相关文章:
CompletableFuture使用详解
一、 CompletableFuture介绍 平时多线程开发一般就是使用Runnable,Callable,Thread,FutureTask,ThreadPoolExecutor这些内容和并发编程息息相关。相对来对来说成本都不高,多多使用是可以熟悉这些内容。这些内容组合在…...
【长期有效】短链接生成-短链接-短网址-短链接生成接口-短链接转换接口-短网址URL生成-短链接-短网址-短域名-短链接
短链接API接口的作用主要体现在以下几个方面: 一、链接缩短与分享优化 短链接API接口的主要功能是将长链接转换为短链接。这种转换使得链接更加简洁、易读和易分享,尤其在社交媒体、电子邮件、短信等字符受限或按字符计费的场合中,短链接能…...
使用Idea自带的git功能进行分支合并
文章目录 1.背景描述2.分支切换3.分支合并的具体操作4.将在local环境下,从dev合并到qas分支上的代码,推送到远端 1.背景描述 目前在开发的当前项目有四个分支,master(主分支)、pre(预生产分支)、qas(测试分支)、dev(开发分支); …...
工业摄像机基于电荷耦合器件的相机
工业摄像机系列产品及其识别技术的详细介绍: 一、工业摄像机概述 工业摄像机是利用光学成像技术获取视觉信息,并通过图像处理算法分析这些信息的设备。它通常具有高图像稳定性、高传输能力和高抗干扰能力等特性,适用于各种复杂的工业环境。 …...
【期末大作业】使用Python熟练掌握面向对象
引言 在编程学习过程中,构建项目是一个非常有效的方式,不仅能巩固和应用所学的知识,还能通过实践来解决实际问题。本文将通过几个经典的项目示例来展示如何用面向对象的方式设计和实现一个完整的系统,包括学生成绩管理系统、图书…...
JAVA:代理模式(Proxy Pattern)的技术指南
1、简述 代理模式(Proxy Pattern)是一种结构型设计模式,用于为其他对象提供一种代理,以控制对这个对象的访问。通过代理模式,我们可以在不修改目标对象代码的情况下扩展功能,满足特定的需求。 设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git 2、什…...
【MAC】深入浅出 Homebrew 下 Nginx 的安装与配置指南
硬件:Apple M4 Pro 16寸 系统: macos Sonoma 15.1.1 Nginx 是一款高性能的 Web 服务器和反向代理服务器,广泛应用于全球各地的网站和企业应用中。本文将详细介绍如何在 macOS 环境下使用 Homebrew 安装、启动、管理以及优化配置 Nginx&#x…...
【华为OD-E卷-寻找关键钥匙 100分(python、java、c++、js、c)】
【华为OD-E卷-寻找关键钥匙 100分(python、java、c、js、c)】 题目 小强正在参加《密室逃生》游戏,当前关卡要求找到符合给定 密码K(升序的不重复小写字母组成) 的箱子,并给出箱子编号,箱子编…...
SQL MID()
SQL中的MID()函数是一个用于从指定位置开始截取字符串中指定长度的子串的函数。这个函数在数据库查询和数据处理中经常被使用,特别是在需要从较长的文本字段中提取特定信息时。 MID()函数的基本语法是:SELECT MID(column_name, start, length) FROM tab…...
Sui 基金会任命 Christian Thompson 为新任负责人
Sui 基金会是专注于推动 Sui 蓬勃发展的生态增长与采用的机构。近日,基金会宣布任命 Christian Thompson 为新任负责人。在 Sui 主网发布的开创性一年里,Sui 凭借其无与伦比的速度、可扩展性和效率,迅速崛起为领先的 Layer 1 区块链之一&…...
ViEW生命周期
Vue的生命周期是指Vue实例从创建到销毁的整个过程,包括多个阶段和对应的钩子函数。以下是Vue生命周期的详细说明: 1. **创建阶段**: - beforeCreate:在实例初始化之前调用,此时数据观测和事件配置尚未完成,…...
[蓝桥杯 2019 国 B] 排列数
目录 前言 题解 思路 疑问 解答 前言 对于本篇文章是站在别人的基础之上来写的,对于这道题作为2019年国赛B组的最难的一题,他的难度肯定是不小的,这道题我再一开始接触的时候连思路都没有,也是看了两三遍别人发的题解&#x…...
python 中执行from elasticsearch import Elasticsearch,AsyncElasticsearch 报错
在 Python 中执行 from elasticsearch import Elasticsearch, AsyncElasticsearch 时,如果提示 AsyncElasticsearch 不存在,可能是因为以下几个原因: 1. 安装的 elasticsearch 库版本不匹配 AsyncElasticsearch 是在 elasticsearch 库的较新版本中引入的。如果你安装的版本…...
git 删除鉴权缓存及账号信息
在Windows系统下 清除凭证管理器中的Git凭据 按下Win R键,打开“运行”对话框,输入control,然后回车,打开控制面板。在控制面板中找到“用户账户”,然后点击“凭据管理器”。在凭据管理器中,找到“Windows…...
浏览器要求用户确认 Cookies Privacy(隐私相关内容)是基于隐私法规的要求,VUE 实现,html 代码
Cookie Notices and Cookie Consent | Cookiepedia 1. 法律法规要求 许多国家和地区的隐私法律要求网站在存储或处理用户数据(包括 Cookies)之前必须获得用户的明确同意: GDPR(欧盟通用数据保护条例) 要求ÿ…...
数据结构:栈和队列的实现
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。 栈中的数据元素遵守后进先出 LIFO ( Last In First Out )的原则。 压栈:栈…...
2024.12.21辩论赛感受
背景 今天辩论赛的双方论点是: 正方:寒假留在研发中心的收获大 反方:寒假去做其他事情的收获 辩论赛,为了锻炼自己,选择了不想选择以及相对不好辩论的反方。出现的状况有一下几点: 1.发现自己脑子完全跟不…...
JAVA:组合模式(Composite Pattern)的技术指南
1、简述 组合模式(Composite Pattern)是一种结构型设计模式,旨在将对象组合成树形结构以表示“部分-整体”的层次结构。它使客户端对单个对象和组合对象的使用具有一致性。 设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git 2、什么是组合模式 组合模式…...
圣诞快乐(h5 css js(圣诞树))
一,整体设计思路 圣诞树h5(简易) 1.页面布局与样式: 页面使用了全屏的黑色背景,中央显示圣诞树,树形由三层绿色的三角形组成,每一层的大小逐渐变小。树干是一个棕色的矩形,位于三角…...
移植 OLLVM 到 LLVM18,修复控制流平坦化报错
版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 前言 把 OLLVM 移植到 LLVM18 后,发现 -fla(控制流平坦化)并不能正常使用。 关于移植过程可以参考这篇文章 【移植 OLLVM…...
MFC/C++学习系列之简单记录——序列化机制
MFC/C学习系列之简单记录——序列化机制 前言简述六大机制序列化机制使用反序列化总结 前言 MFC有六大机制,分别是程序启动机制、窗口创建机制、动态创建机制、运行时类信息机制、消息映射机制、序列化机制。 简述六大机制 程序启动机制:全局的应用程序…...
【网络云计算】2024第51周-每日【2024/12/17】小测-理论-解析
文章目录 1. 计算机网络有哪些分类2. 计算机网络中协议与标准的区别3. 计算机网络拓扑有哪些结构4. 常用的网络设备有哪些,分属于OSI的哪一层5. IEEE802局域网标准有哪些 【网络云计算】2024第51周-每日【2024/12/17】小测-理论-解析 1. 计算机网络有哪些分类 计算…...
Python中的上下文管理器:从资源管理到自定义实现
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 Python中的上下文管理器(Context Manager)为资源管理提供了强大的支持,尤其在处理文件、网络连接、数据库连接等需要精确控制生命周期的…...
STM32 高级 物联网通信之CAN通讯
目录 CAN通讯介绍 物理层 协议层 CAN的帧(报文)种类 1 数据帧(发送单元->接受单元) 2 远程帧(接受单元->发送单元) 3 错误帧(发送方发送数据错误会发送的状态帧) 4 过载帧(接收方放不下会发送到的状态帧) 5 帧间隔(状态) 数据帧介绍 远程帧介绍 C…...
如何求解小于等于x的正整数因子y的个数总和
G ( X , Y ) X 的因子 Y 个数 G(X,Y) X的因子Y个数 G(X,Y)X的因子Y个数 例如 G ( 8 , 2 ) 3 G(8,2)3 G(8,2)3 G ( 12 , 2 ) 2 G(12,2)2 G(12,2)2 F ( X , Y ) ∑ i 1 X G ( i ) F(X, Y) \sum_{i1}^{X} G(i) F(X,Y)i1∑XG(i) 直接上结论 F ( X , Y ) X Y 1 ⋯ X…...
Epic游戏使用mod
以土豆兄弟为例: 第一步:获取 SteamCMD 下载官方 Steam 控制台客户端 (steamCMD) 1. 下载好后打开,是一个在 cmd 窗口的运行的命令行 2. 输入以下代码登录 login anonymous 第二步: 确认自己要下载的游戏 ID 和 mod ID 然后…...
前端:纯前端快速实现html导出word和pdf
实现html导出word,需要使用两个库。 html-docx-js和file-saver 导出word的js方法 > npm install html-docx-js >npm install file-saver js引入 import FileSaver from “file-saver”; import htmlDocx from “html-docx-js/dist/html-docx”; /**导出…...
Windows装Docker至D盘/其他盘(最新,最准确,直接装)
前言 Docker的默认安装路径为 C:\你的用户名\AppData\Local\Docker\wsl这样安装常常会导致C盘爆满。目前现有博客的安装方法往往不能把docker的container和image也装在非C盘。本博客旨在用最简单的方式,把Docker Deskstop的images和container装在D盘中。 安装前&a…...
2024 年 IA 技术大爆发深度解析
摘要: 本文旨在深入剖析 2024 年 IA 技术大爆发所引发的多方面反响。通过对产业变革、经济影响、就业市场、社会影响、政策与监管以及未来展望等维度的探讨,揭示 IA 技术在这一关键时期对全球各个层面带来的深刻变革与挑战,并提出相应的思考与…...
现代 CSS 布局与响应式设计实战指南
作为一名前端开发者,我经常被问到:"为什么你的页面布局这么流畅?响应式适配这么完美?"今天,我就来分享一下在实际项目中常用的 CSS 布局技巧和响应式设计方案。 现代布局三剑客:Flex、Grid 和 C…...
react 项目打包二级目 使用BrowserRouter 解决页面刷新404 找不到路由
使用BrowserRouter package 配置 (这部分代码可以不做配置也能实现) {"homepage": "/admin",}vite.config 配置 export default defineConfig({base: /admin])BrowserRouter 添加配置项 <BrowserRouter basename/admin>&l…...
Yolo11改进策略:Block改进|使用FastVit的RepMixerBlock改进Yolo11,重参数重构助力Yolo11涨点(全网首发)
文章目录 摘要FastViT:一种使用结构重新参数化的快速混合视觉变换器1、简介2、相关工作3、体系结构3.1、概述3.2、FastViT3.2.1、重新参数化跳过连接3.2.2、线性训练时间过参数化3.2.3、大核卷积4、实验4.1、图像分类4.2、鲁棒性评价4.3、3D Hand网格估计4.4、语义分割和目标检…...
2.6 网络面试问题
tcp 与 udp的区别 1.tcp 是基于连接的 UDP是基于数据包 2.处理并发的方式不通 a.tcp用epoll进行监听的 b. udp是模拟tcp的连接过程,服务端开放一个IP端口,收到连接后,服务端用另一个IP和端口发包给客户端。 3.tcp根据协议MTU黏包及…...
02-10.python入门基础一Python模块与包(二)
五、Python 包的概念 (一)包的定义与结构 在 Python 中,“包”(Package)是一种按照目录来组织模块的方式,它允许开发者将相关的模块集合在一起,形成一个更具逻辑性和结构性的代码单元。 从物…...
[WiFi] WiFi 802.1x介绍及EAP认证流程整理
802.1X Wi-Fi 802.1X 是一种网络访问控制协议,常用于保护无线网络。它提供了一种基于端口的网络访问控制机制,主要用于在用户和网络之间建立安全的连接。以下是 802.1X 的一些关键特点: 认证框架 802.1X 使用 EAP(可扩展认证协议…...
前端通过new Blob下载文档流(下载zip或excel)
当后端返回这样的预览: 前端该如何下载呢?首先在axios请求里,加入第三个参数{ responseType: ‘blob’ }。 proxy.$post(url, params, { responseType: blob }).then((res)>{downloadFormat(res) });然后在一个函数里处理返回,…...
R 常用的内置软件包及功能介绍
R 中有许多内置包,提供了丰富的功能来帮助用户进行数据分析、统计建模、图形可视化等任务。以下是一些常用的内置包及其功能简介: 1. stats 包 stats 是 R 的一个核心包,几乎每个 R 用户都会使用它。它包含了许多统计分析的函数,…...
基于 HC_SR04的超声波测距数码管显示(智能小车超声波避障部分)
超声波测距模块HC-SR04 1、产品特色 ①典型工作用电压:5V ②超小静态工作电流:小于 5mA ③感应角度(R3 电阻越大,增益越高,探测角度越大): R3 电阻为 392,不大于 15 度 R3 电阻为 472, 不大于 30 度 ④探测距离(R3 电阻可调节增益,即调节探测…...
12月第十九讲:Redis应用Redis相关解决方案
1.数据库与缓存一致性方案 2.热key探测系统处理热key问题 3.缓存大value监控和切分处理方案 4.Redis内存不足强制回收监控告警方案 5.Redis集群缓存雪崩自动探测 限流降级方案 6.缓存击穿的解决方法 线上Redis比较严重的问题排序是:数据库和缓存一致性、热key…...
solon 集成 activemq-client (sdk)
原始状态的 activemq-client sdk 集成非常方便,也更适合定制。就是有些同学,可能对原始接口会比较陌生,会希望有个具体的示例。 <dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-client&l…...
STM32-笔记7-继电器定时开闭
1、复制02项目,重命名08-继电器定时开闭 打开项目工程 在\Drivers\BSP\该路径下,新建alarm文件夹,该文件夹下里面包含alarm.c和alarm.h文件 加载进该项目中 为什么这里使用的是 这个单词,而不是继电器(relay&#…...
B4X编程语言:B4X的映射(数据地图Map)详解
B4X的映射(Map)是由多个键值对组成的数据集合,也称为数据地图。它和列表一样也是一个非可视化的数据容器,在B4X中作为变量使用,用于在单个变量下存储多个键值对。 映射中的键是唯一的。 这意味着,如果您添加了一个键/值对…...
windows C++ 判断文件大小,清空文件,写日志
windows C 判断文件大小,清空文件,写日志等几个常见的接口,记录一下备忘 #include <iostream> #include <vector> #include<Windows.h> #include<string> #include <iostream> #include <sys/types.h> …...
用Python设置Excel工作表的页眉和页脚
在处理和分析数据时,Excel作为一款功能强大的工具,被广泛应用于各个领域。当涉及到打印或分享工作表时,为文档添加专业的页眉和页脚不仅能提升文件的视觉效果,还能提供必要的信息,例如公司标识、日期、文件名或是页码等…...
electron-vite【实战】自定义标题栏【组件封装】(含异形标题栏,指定区域拖拽,窗口置顶,窗口最小化,窗口最大化,取消最大化,隐藏窗口到托盘等)
效果预览 技术要点 透明背景 src/main/index.ts 的 new BrowserWindow 中添加 transparent: true, // 设置窗口背景透明frame: false, // 隐藏窗口边框仅图标和标题部分可拖拽 仅图标和标题部分添加样式 drag .drag {-webkit-app-region: drag; }图标与标题栏的融合 标题栏的…...
MySQL复制问题和解决
目录 环境介绍 一,主库执行delete,从库没有该数据 模拟故障 修复故障 二,主库执行insert,从库已存在该数据 模拟故障 故障恢复 三,主库执行update,从库没有该数据 模拟故障 故障恢复 四…...
Spark和Hive的区别
1 、 Hive Hive 是基于 Hadoop 的数据仓库工具,同时又是查询引擎, Spark SQL 只是取代的 Hive 的查询引擎这一部分,企业可以使用HiveSpark SQL 进行开发。 Hive 的主要工作如下: 把HQL 翻译长 map-reduce 的代码,并…...
Type-C 接口电热毯:开启温暖智能新时代
在当今科技迅猛发展的时代,智能家居产品如同璀璨繁星般点缀着我们的生活,从智能灯光的温馨到温控系统的精准,处处都彰显着科技赋予生活的便捷与舒适。而在这股追求高效与智能化的洪流之中,一款极具创新的电热毯——Type-C 接口电热…...
React 19新特性探索:提升性能与开发者体验
React作为最受欢迎的JavaScript库之一,不断推出新版本以应对日益复杂的应用需求。React 19作为最新的版本,引入了一系列令人兴奋的新特性和改进,旨在进一步提升应用的性能、开发效率和用户体验。 本文将深入探讨React 19的新特性,…...
【数据库】SQL语句基础
【数据库】SQL语句基础 文章目录 【数据库】SQL语句基础一、SQL与数据库二、 SQL语句类型2.1 数据定义语言(DDL)1. 创建数据库:CREATE DATABASE2. 创建表:CREATE TABLE3. 删除表:DROP TABLE4. 修改表结构:A…...