java中Future使用详细介绍
一、什么是Future?
在并发编程中,可以通过Future对象来异步获取结果。
使用Thread或runnable接口都不能获取异步的执行结果,因为他们没有返回值。而通过实现Callable接口和Future就可以获取异步执行的结果,当异步执行结束后,返回结果将保存在Future中。使用Future就可以让我们暂时去处理其他的任务而无需一直等待结果,等异步任务执行完毕再返回其结果。
二、Future中的get方法
1、get方法
获取任务结束后返回的结果,如果调用时,任务还没有结束,则会进行阻塞线程,直到任务完成。该阻塞是可以被打断的,打断的线程是调用get方法的线程,被打断后原任务会依旧继续执行。
V get() throws InterruptedException, ExecutionException;
2、指定时间的get方法
获取任务结束后返回的结果,如果调用时,任务还没有结束,则会进行阻塞线程,等待一定时间,如果在规定时间内任务结束则返回结果,否则抛出TimeoutException,超时后任务依旧会继续执行。该阻塞是可以被打断的,打断的线程是调用get方法的线程,被打断后原任务会依旧继续执行。
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
三、Future代码示例
步骤1:创建一个线程池
public class AsyncTaskExecutor {/*** 核心线程数*/private static final int corePoolSize = 10;/*** 最大线程数*/private static final int maxPoolSize = 30;/*** 空闲线程回收时间* 空闲线程是指:当前线程池中超过了核心线程数之后,多余的空闲线程的数量*/private static final int keepAliveTime = 100;/*** 任务队列/阻塞队列*/private static final int blockingQueueSize = 99999;private static final ThreadPoolExecutor executorPool = new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(blockingQueueSize),new ThreadFactoryBuilder().setNameFormat("AsyncTaskThread" + "-%d").build(),new ThreadPoolExecutor.CallerRunsPolicy());/*** 异步任务执行** @param task*/public static void execute(Runnable task) {executorPool.execute(task);}/*** 异步执行任务Callable, 通过Future获取结果** @param task* @param <T>* @return*/public static <T> Future<T> submit(Callable<T> task) {return executorPool.submit(task);}/*** 异步执行任务Runnable,通过Future获取结果** @param task* @return*/public static Future<?> submit(Runnable task) {return executorPool.submit(task);}}
步骤2:编写测试类
@Testpublic void test2() {try {Future<String> future = AsyncTaskExecutor.submit(() -> {log.info("[Future Task] future task start...");try {//模拟任务执行Thread.sleep(5000);} catch (InterruptedException e) {log.info(e.getMessage());}log.info("[Future Task] future task end...");return "Task completed...";});//执行其他任务log.info("[Main Thread] main thread is running...");//使用future阻塞等待任务完成,并获取结果String futureResult = future.get();log.info("[Main Thread] {}", futureResult);}catch (Exception e) {e.printStackTrace();}}
步骤3:查看结果
2024-05-28 10:58:23.633 INFO 1184 --- [ main] com.example.demo.dao.UserDaoTest : [Main Thread] main thread is running...
2024-05-28 10:58:23.633 INFO 1184 --- [yncTaskThread-0] com.example.demo.dao.UserDaoTest : [Future Task] future task start...
2024-05-28 10:58:28.633 INFO 1184 --- [yncTaskThread-0] com.example.demo.dao.UserDaoTest : [Future Task] future task end...
2024-05-28 10:58:28.634 INFO 1184 --- [ main] com.example.demo.dao.UserDaoTest : [Main Thread] Task completed...
四、ListenableFuture
public class AsyncTaskExecutor {/*** 核心线程数*/private static final int corePoolSize = 10;/*** 最大线程数*/private static final int maxPoolSize = 30;/*** 空闲线程回收时间* 空闲线程是指:当前线程池中超过了核心线程数之后,多余的空闲线程的数量*/private static final int keepAliveTime = 100;/*** 任务队列/阻塞队列*/private static final int blockingQueueSize = 99999;private static final ThreadPoolExecutor executorPool = new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(blockingQueueSize),new ThreadFactoryBuilder().setNameFormat("AsyncTaskThread" + "-%d").build(),new ThreadPoolExecutor.CallerRunsPolicy());/*** 创建一个ListeningExecutorService,用于执行异步任务* (通过submit提交任务,以ListenableFuture获取结果)*/private static final ListeningExecutorService LISTENING_EXECUTOR = MoreExecutors.listeningDecorator(executorPool);/*** 异步任务执行** @param task*/public static void execute(Runnable task) {executorPool.execute(task);}/*** 异步执行任务Callable, 通过ListenableFuture获取结果** @param task* @param <T>* @return*/public static <T> ListenableFuture<T> submit(Callable<T> task) {return LISTENING_EXECUTOR.submit(task);}/*** 异步执行任务Runnable,通过Future获取结果** @param task* @return*/public static ListenableFuture<?> submit(Runnable task) {return LISTENING_EXECUTOR.submit(task);}
}
@Testpublic void test2() {try {
// sqlSession = MybatisUtils.getSqlSession();
// UserDao mapper = sqlSession.getMapper(UserDao.class);
// boolean x = mapper.addUser(new User(6, "eeee", "eeee", "school666"));
// if (x == true) {
// log.info("OK..........");
// mapper.getUserList().forEach(user -> System.out.println(user));
// }// //步骤1:创建异步任务
// CommonTask task = new CommonTask(1L, ModelEnum.Chinese);
// //步骤2:调用线程池异步执行任务
// AsyncTaskExecutor.execute(task);
// log.info("main thread over...");CompletableFuture<School> schoolFuture = new CompletableFuture<>();ListenableFuture<School> listenableFuture1 = AsyncTaskExecutor.submit(() -> {try {//模拟任务执行Thread.sleep(2000);} catch (InterruptedException e) {log.info(e.getMessage());}return new School("DSchool");});ListenableFuture<School> listenableFuture2 = AsyncTaskExecutor.submit(() -> {try {//模拟任务执行Thread.sleep(2000);} catch (InterruptedException e) {log.info(e.getMessage());}return new School("ESchool");});Futures.successfulAsList(listenableFuture1, listenableFuture2).get();School resSchool = listenableFuture1.get(3000, TimeUnit.MILLISECONDS);log.info("[Main Thread] result is {}", JSON.toJSON(resSchool));}catch (Exception e) {e.printStackTrace();}}
相关文章:
java中Future使用详细介绍
一、什么是Future? 在并发编程中,可以通过Future对象来异步获取结果。 使用Thread或runnable接口都不能获取异步的执行结果,因为他们没有返回值。而通过实现Callable接口和Future就可以获取异步执行的结果,当异步执行结束后&…...
docker和containerd的区别
docker和containerd的区别 1、容器运行时 1.1 容器运行时概念 容器运行时(Container Runtime)是一种负责在操作系统层面创建和管理容器的软件工具或组件。它是容器化技术的核心组件之一,用于在容器内部运行应用程序,并提供隔离…...
汇编实现流水灯
1.使能时钟: 1使能GPIO的外设时钟ldr r0,0x50000A28ldr r1,[r0]orr r1,r1,#(0x3<<4)//使能第4,5位str r1,[r0] 2.设置为输出模式 设置GPIOE10为输出模式ldr r0,0x50006000ldr r1,[r0]bic r1,r1,#(0x3<<20)orr r1,r1…...
SQL生成序列浅析
01.sqlserver版本 使用sqlserver将数据复制n条 selectt.indx,t.name,tmp.vlue from (values(1,苹果) ) as t(indx, name) ,(select[number] as vluefrom master.dbo.spt_valueswhere [type] pand [number] between 1 and 10 ) as tmpspt_values是什么 spt_values是SQL Se…...
24年gdcpc省赛C题
1279:DFS 序 先不考虑多节点,先看着颗二叉树,假设他们的父亲节点是第k个被访问的点,如果先访问左子树,那么得到的结果是a1*ka2*(k1)b1*(2k)b2*(2k1),可以发现,先访问左子树,那么右子树每次的乘以的p值实际上是左子树乘以的p值加上左子树的节点个数,比如a1*k和b1*(2k),如果不看2…...
以梦为马,不负韶华(3)-AGI在企业服务的应用
AGI在企业服务中,各应⽤已覆盖企业全流程,包含⼈⼒、法务、财税、流程⾃动化、知识管理和软件开发各领域。 由于⼤语⾔模型对⽂本处理类场景有着天然且直接的适配性,⽂本总结、⽂本内容⽣成、服务指引等发展起步早且应⽤成熟度更⾼。 在数据…...
Xshell 使用
Xshell 使用 ①xshell 安装包 ②xshell 卸载 ③xshell 同时控制多窗口 ①xshell 安装包 Xshell 7 破解版 ②xshell 卸载 第一步: 打开控制面板卸载xshell 第二步: win+R,输入regedit,打开注册表,删除xshell相关注册信息 注册表目录: 在下面两个目录中查找xshell相关…...
【yijiej】mysql报错 之 报错:Duplicate entry 字段 for key ‘表名.idx_字段’
一、问题操作 Mysql 进行insert 操作,报错:Duplicate entry 字段 for key ‘表名.idx_字段’ 原因解析:idx 是做的索引键,是具有唯一性二、问题原因(三种情况,当前我遇到的情况是第一种) 1、当 …...
解决npm卡死,无法安装依赖
npm卡死,无法安装依赖 异常描述原因分析与解决方法 异常描述 1.无法进入命令行,或是很慢没反应 2.装表格无限滚动的el-table-infinite-scroll依赖一上午了,也不能装,报错提示 原因分析与解决方法 1.命令行的问题:缓…...
速卖通测评揭秘:如何选择安全的渠道操作
许多商家对测评存在误解,认为只需进行几次测评就能迅速打造爆款。实际上,测评是一个需要计划和持久性的过程,以便让平台检测到产品的受众程度并提高产品的曝光和权重。 在进行测评时,安全是首要考虑的问题。平台可以通过设备、网…...
ping不通ip的解决方法
解决ping不通IP的问题可以通过以下几种方法: 1.检查IP配置:确保所有设备的IP地址、子网掩码和默认网关配置正确。如果使用DHCP,请确认设备已设置为自动获取IP地址,并检查DHCP服务器的地址池配置是否正确且未耗尽。 2.检查网络设…...
Linux x86_64 UEFI 启动
文章目录 前言一、UEFI二、Disk device compatibility2.1 GPT 磁盘分区表2.1.1 简介2.1.2 Linux 2.2 ESP(EFI) 文件系统2.2.1 简介2.2.2 LinuxLinux Kernel EFI Boot Stub 三、UEFI GPT grub23.1 简介3.2 引导方式 3.3 BOOTX64.EFI3.4 shimx64.efi3.5 …...
妙解设计模式之适配器模式
目录 适配器模式的概念生活中的例子在编程中的例子 软件工程中的实际应用兼容旧接口整合第三方库简化复杂接口跨平台支持 总结 适配器模式的概念 适配器模式是一种结构设计模式,它允许将接口不兼容的类通过一个适配器类进行适配,使得这些类可以一起工作…...
【Linux】Linux下centos更换国内yum源
🌱博客主页:青竹雾色间 🌱系列专栏:Linux 😘博客制作不易欢迎各位👍点赞⭐收藏➕关注 目录 1. 备份旧的 YUM 源文件2. 下载国内的 YUM 源文件阿里云:网易: 3. 清理 YUM 缓存4. 更新…...
HTML静态网页成品作业(HTML+CSS)——动漫熊出没介绍网页(3个页面)
🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有3个页面。 二、作品演示 三、代…...
算法训练营day42
dp含义确定 递推公式 初始化 遍历顺序 打印 题目1:62. 不同路径 - 力扣(LeetCode) class Solution { public:int uniquePaths(int m, int n) {// 定义dp数组 含义是每个坐标到达的路径vector<vector<int>> dp(m, vector&l…...
【Vue】自动导入组件
1. 下载插件 npm install unplugin-vue-components 2. 修改vite.config.js import { fileURLToPath, URL } from node:urlimport { defineConfig } from vite import vue from vitejs/plugin-vue import Components from unplugin-vue-components/vite // 按需加载自定义组件/…...
mfc140u.dll丢失的解决方法有哪些?怎么全面修复mfc140u.dll文件
mfc140u.dll丢失其实相对来说不太常见到,因为这个文件一般是不丢失的,不过既然有人遇到这种问题,那么小编一定满足各位,给大家详细的唠叨一下mfc140u.dll丢失的各种解决方法,教大家以最快最有效率的方法去解决mfc140u.…...
MySQL8报错Public Key Retrieval is not allowedz 怎么解决?
问题描述 当我们使用数据库管理工具连接mysql8的时候,可能遇到报错: Public Key Retrieval is not allowed 解决办法 1、在连接属性中配置allowPublicKeyRetrieval设置为true 2、在连接URL中加上配置allowPublicKeyRetrieval为true...
海外动态IP代理如何提高效率?
动态住宅IP代理之所以能够有效提升数据爬取的效率和准确性,主要归功于其提供的IP地址具有高度的匿名性和真实性。这些IP地址来自于真实的用户网络,因此相比于数据中心IP,它们更不容易被网站的安全系统标识为爬虫。此外,由于IP地址…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
