Java异步任务编排
多线程创建的五种方式:
- 继承Thread类
- 实现runnable接口。
- 实现Callable接口 + FutureTask(可以拿到返回结果,阻塞式等待。)
- 线程池创建。
ExcutorService service = Excutors.newFixedThreadPool(10);
service.excute(new Runnable01());
- 另外一种创建线程池的方式:
ThreadPoolExecutor executor = new ThreadPoolExcutor();// 七大参数:
corePoolSize:核心线程数
maximumPoolSize:最大线程数
keepAliveTime:线程最大回收时间。即线程空闲的最大时间。超过该时间就销毁。
unit:时间单位。回收线程的时间的单位。
workQueue:阻塞队列。当核心线程数满了,剩余的线程将在阻塞队列中等待。
threadFactory:创建线程的工厂。
RejectedExecutionHandler:核心线程满了,阻塞队列中也满了,同时额外建立的非核心线程数(最大线程数-核心线程数)也都用完了,此时将采取拒绝策略。
max都执行完成,有很多空闲。在指定的时间keepAliveTime以后,就会释放max-core这些线程。
LinkedBlockingQueue:默认大小是Integer的最大值。可能导致内存不足。
// 核心线程数为0 , 非核心线程数是Integer的最大值。所有线程都可回收。
Executors.newCachedThreadPool();// 固定线程池,核心线程数和最大线程数一样,都是传入的值。 核心=最大,都一直不会回收
Executors.newFixedThreadPool(10);// 做定时任务调度的线程池。
Executors.newScheduledThreadPool(10);// 单线程的线程池,后台从队列中获取任务,挨个执行。
Executors.newSingleThreadExecutor()
异步编排
创建异步编排对象
CompletableFuture.runAsync(() -> {} , executorService);CompletableFuture.supplyAsync(() -> {} , executorService);
supply开头:这种方法,可以返回异步线程执行之后的结果
run开头:这种不会返回结果,就只是执行线程任务
- CompletableFuture.whenComplete():感知异步线程的执行结果。但是无法返回。
- CompletableFuture.exceptionally():处理异常,只要有异常,会进入该方法处理。然后返回一个对应的结果。
- CompletableFuture.handle():用于处理返回结果,可以接收返回值和异常,可以对返回值进行修改。
CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {return "hello";
}, executorService).whenCompleteAsync((res , throwable) -> {System.out.println("stringCompletableFuture whenCompleteAsync:" + res);throw new RuntimeException("hhhhhh");
}, executorService).exceptionally((throwable) -> {return "jimo";
});System.out.println("stringCompletableFuture:" + stringCompletableFuture.get());
线程串行方法
CompletableFuture.supplyAsync(() -> {return 1;
},executorService).thenRunAsync(() -> {System.out.println("串行化执行。。。。");
} , executorService);
CompletableFuture.supplyAsync(() -> {return "n";
} , executorService).thenAcceptAsync((res) -> {System.out.println(res + "串行化:执行结果:" + res);
});
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {return "急急急";
}, executorService).thenApplyAsync((res) -> {return "ddd" + res;
});
System.out.println(future.get());
// 使线程串行执行,不感知上一线程执行的结果,也不返回当前线程执行的结果。
public CompletableFuture<Void> thenRun(Runnable action);
public CompletableFuture<Void> thenRunAsync(Runnable action);
public CompletableFuture<Void> thenRunAsync(Runnable action, Executor executor);// 使线程串行执行,感知上一线程执行的结果,不返回当前线程执行的结果。
public CompletableFuture<Void> thenAccept(Consumer<? super T> action);
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action);
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor);// 使线程串行执行,感知上一线程执行的结果,返回当前线程执行的结果。
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn);
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor);
Async的是可以指定线程池,使用一个新的线程。
不带Async的是使用串行前面那个线程继续执行。
两任务并行执行完成,再执行新任务
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {System.out.println("任务1正在执行。。。");return 1;
}, executorService);CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {System.out.println("任务2正在执行。。。");return 2;
}, executorService);// 两个都执行完后执行。无法获取两个任务的返回值。自己也没有返回值。
future1.runAfterBothAsync(future2 , () -> {System.out.println("两个任务都执行完了。。。");
} , executorService);// 两个任务都执行完之后执行新任务,可以获取到两个任务的返回值,自己没有返回值
future1.thenAcceptBothAsync(future2 , (res1 , res2) -> {System.out.println("两个任务都执行完了。。。");System.out.println(res1 + ":::::" + res2);
} , executorService);
// 线程并行执行完成,并且执行新任务action,新任务无入参,无返回值
public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other, Runnable action);
public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);
public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);// 线程并行执行完成,并且执行新任务action,新任务有入参,无返回值
public <U> CompletableFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);// 线程并行执行完成,并且执行新任务action,新任务有入参,有返回值
public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);
两任务执行完任意一个任务,即可执行新任务。
// 不感知执行完的线程的返回值,自己也不返回任何值。
CompletableFuture<Void> future = future1.runAfterEitherAsync(future2, () -> {System.out.println("两个任务重完成了一个任务了,可以执行新任务");
}, executorService);// 感知执行完的线程的返回值,自己也不返回任何值。
future1.acceptEitherAsync(future2 , (res) -> {System.out.println("两线程中的任意一个线程的结果:" + res);
} , executorService);// 感知执行完的线程的返回值,自己也返回值。
CompletableFuture<String> stringCompletableFuture = future1.applyToEitherAsync(future2, (res) -> {return res + "姚云峰";
}, executorService);
System.out.println(stringCompletableFuture.get());
// 任务并行执行,只要其中有一个执行完,就开始执行新任务action,新任务无入参,无返回值
public CompletableFuture<Void> runAfterEither(CompletionStage<?> other, Runnable action);
public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other, Runnable action);
public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other, Runnable action, Executor executor);// 任务并行执行,只要其中有一个执行完,就开始执行新任务action,新任务有入参(入参类型为Object,因为不确定是哪个任务先执行完成),无返回值
public CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action);
public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action);
public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action,Executor executor);// 任务并行执行,只要其中有一个执行完,就开始执行新任务action,新任务有入参(入参类型为Object,因为不确定是哪个任务先执行完成),有返回值
public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn);
public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn,Executor executor);
多任务组合 都完成才返回。完成一个即返回。
// 完成一个即返回。
public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs);
// 两任务完成1任务后即可执行。acceptEitherAsync可以感知之前的结果,自己有返回值。
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {System.out.println("查询图片信息。");return "Hello.jpg";
});CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {System.out.println("查询属性信息。");try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}return "黑色256G";
});CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {System.out.println("查询商品介绍信息。");return "华为";
});// 等待这三个都做完。
CompletableFuture<Void> all = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
System.out.println(all.get());
System.out.println("main end");
System.out.println("main end " + futureImg.get() + " " + futureAttr.get() + " " + futureDesc.get());
// 等待三个中的一个完成即可。
CompletableFuture<Object> any = CompletableFuture.anyOf(futureImg, futureAttr, futureDesc);
System.out.println(any.get());
// System.out.println("main end " + futureImg.get() + " " + futureAttr.get() + " " + futureDesc.get());
System.out.println("main end ");
相关文章:
Java异步任务编排
多线程创建的五种方式: 继承Thread类实现runnable接口。实现Callable接口 FutureTask(可以拿到返回结果,阻塞式等待。)线程池创建。 ExcutorService service Excutors.newFixedThreadPool(10); service.excute(new Runnable01());另外一种创建线程池…...

Hive与HBase的区别及应用场景
当数据量达到一定量级的时候,存储和统计计算查询都会遇到问题,今天了解一下Hive和Hbase的区别和应用场景。 一、定义 Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能&am…...

C++之单例模式
目录 1. 请设计一个类,只能在堆上创建对象 2. 请设计一个类,只能在栈上创建对象 3.请设计一个类,不能被拷贝 C98 C11 4. 请设计一个类,不能被继承 C98 C11 5. 请设计一个类,只能创建一个对象(单例模式) 设计…...

Redis十大类型——Set与Zset常见操作
Redis十大类型——Set与Zset常见操作Set命令操作简列基本操作展示删除移动剪切集合运算Zset基本操作简列添加展示反转按分数取值获取分数值删除分数操作下标操作如果我们对Java有所了解,相信大家很容易就明白Set,在Redis中也一样,Set的value值…...

车载雷达实战之Firmware内存优化
内存(Memory)是计算机中最重要的部件之一,计算机运时的程序以及数据都依赖它进行存储。内存主要分为随机存储器(RAM),只读存储器(ROM)以及高速缓存(Cache)。仅仅雷达的原…...

【剑指Offer】JZ14--剪绳子
剪绳子详解1.问题描述2.解题思路3.具体实现1.问题描述 2.解题思路 首先想到的思路:因为是求乘积的最大值,所以如果截取剩下的是1,那还是它本身就没有意义。从此出发,考虑绳子长度是2、3、4、5…通过穷举法来找规律。 值–》拆分–…...

raspberry pi播放音视频
文章目录目的QMediaPlayerGStreamerwhat is GStreamer体系框架优势omxplayerwhat is omxplayercommand Linekey bindings运行过程中错误ALSA目的 实现在树莓派下外接扬声器, 播放某段音频, 进行回音测试。 QMediaPlayer 首先我的安装是5.11版本。 优先…...

【电子学会】2022年12月图形化二级 -- 老鹰捉小鸡
老鹰捉小鸡 小鸡正在农场上玩耍,突然从远处飞来一只老鹰,小鸡要快速回到鸡舍中,躲避老鹰的抓捕。 1. 准备工作 (1)删除默认白色背景,添加背景Farm; (2)删除默认角色小…...

C++的双端队列
双端队列介绍1.双端队列知识需知2.大试牛刀1.双端队列知识需知 由于队列是一种先进先出(FIFO)的数据结构,因此无法直接从队列的底部删除元素。如果希望从队列的底部删除元素,可以考虑使用双端队列(deque)。…...
【独家】华为OD机试 - 拼接 URL(C 语言解题)
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明本期…...

为什么使用Junit单元测试?Junit的详解
Hi I’m Shendi 为什么使用Junit单元测试?Junit的详解 Junit简介 Junit是一个Java语言的单元测试框架。 单元测试是一个对单一实体(类或方法)的测试 JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression test…...
怎么学好嵌入式Linux系统和驱动
嵌入式专业是一门实践性非常强的学科,只有多动手,多实践,多编程,多调试,多看书,多思考才能真正掌握好嵌入式开发技术。 现在很多同学也意识到了学校培养模式和社会需求脱节问题,有一部分同学也先…...

Spring Aware总结
概述 Spring中Aware到底是什么意思? 我们在看Spring源码的时候,经常可以看到xxxAwarexxx的身影,通常我会很疑惑,Aware到底是什么意思呢? 比如图片中这些包含Aware关键字的类或者接口。 我对下面3个类或接口进行了解…...
【RocketMQ】源码详解:Broker端消息刷盘流程
消息刷盘 同步入口:org.apache.rocketmq.store.CommitLog.GroupCommitService 异步入口:org.apache.rocketmq.store.CommitLog.FlushRealTimeService 刷盘有同步和异步两种,在实例化Commitlog的时候,会根据配置创建不同的服务 p…...

编码器SIQ-02FVS3驱动
一.简介 此编码器可以是功能非常强大,可以检测左右转动,和按键按下,所以说这一个编码器可以抵三个按键,而且体积非常小,使用起来比三个按键要高大尚,而且驱动也简单。唯一不足的点就是价格有点小贵6-8元才…...

【2021.9.7】记一次exe手动添加shellcode
【2021.9.7】记一次exe手动添加shellcode 文章目录【2021.9.7】记一次exe手动添加shellcode0.大致思路1.获取MessageBox的真实地址VA2.通过OD在代码段添加shellcode3.dump出数据,设置程序OEP4.测试dump出来的exe5.方法总结测试的exe和添加了shellcode的exe:链接&…...

常用训练tricks,提升你模型的鲁棒性
目录一、对抗训练FGM(Fast Gradient Method): ICLR2017代码实现二、权值平均1.指数移动平均(Exponential Moving Average,EMA)为什么EMA会有效?代码实现2. 随机权值平均(Stochastic Weight Averaging,SWA&a…...

具有精密内部基准的 DACx0502 简介及驱动应用示例
DACx0502 说明 16 位 DAC80502、14 位 DAC70502 和 12 位DAC60502 (DACx0502) 数模转换器 (DAC) 均为具有电压输出的高精度、低功耗器件。 DACx0502 线性度小于 1LSB。凭借高精度和微型封装特性,DACx0502 非常适合以下 应用: 增益和失调电压校准、电流…...

C语言函数:字符串函数及模拟实现strncpy()、strncat()、strncmp()
C语言函数:字符串函数及模拟实现strncpy()、strncat()、strncmp() 在了解strncpy、strncat()、前,需要先了解strcpy()、strncat(): C语言函数:字符串函数及模拟实现strlen() 、strcpy()、 strcat()_srhqwe的博客-CSDN博客 strncp…...
学术论文插图要求简介
1. 类型 位图和矢量图是两种不同的图像类型,它们在存储和处理图像时使用不同的方法。以下是它们之间的详细区别: 图像构成方式:位图使用像素(或图像的最小单元)来构建图像,每个像素都有自己的颜色和亮度值。…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...