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

自定义封装异步任务组件,实现FutureTask功能

  • FutureTask

在 JDK1.8 后的异步编排API中的CompletableFuture,提供了 异步任务的成功回调、异常回调。

public class FutureTaskTest {public static void main(String[] args) throws Exception {CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}return UUID.randomUUID().toString();});future.thenAccept((s) -> {System.out.println("异步任务的返回值" + s);});future.exceptionally((ex) -> {ex.printStackTrace();return null;});Thread.sleep(5000);}}

启动一个异步任务后,就相当于启动了一个线程,给这个异步对象设置回调方法,那么当异步任务运行结束或者出现异常时会自动调用相关的回调。

  • 自定义AsyncTask实现 异步任务回调
public class AsyncTest {public static void main(String[] args) throws Exception {AsyncTask<String> asyncTask = new AsyncTask<>(new Callable<String>() {@Overridepublic String call() throws Exception {System.out.println("开始处理数据");Thread.sleep(3000);String s = UUID.randomUUID().toString();System.out.println("数据计算完成");return s;}});asyncTask.run();Thread.sleep(5000);asyncTask.thenError((ex) -> {ex.printStackTrace();});asyncTask.thenSuccess((s) -> {System.out.println("任务数据:" + s);});System.out.println("主线程结束");}}class AsyncTask<T>{private Callable<T> task;private T value;private Exception e;private Consumer<T> successConsumer;private Consumer<? super Exception> exConsumer;private Thread thread;public AsyncTask(Callable<T> task){this.task = task;}public void run(){this.thread = new Thread(() -> {try {value = task.call();if (successConsumer != null){successConsumer.accept(value);}} catch (Exception e) {this.e = e;if (exConsumer != null){exConsumer.accept(e);}}});this.thread.start();}public void thenSuccess(Consumer<T> consumer){this.successConsumer = consumer;if (this.thread != null && !this.thread.isAlive() && e == null){consumer.accept(value);}}public void thenError(Consumer<? super Exception> consumer){this.exConsumer = consumer;if (this.thread != null && !this.thread.isAlive() && e != null){consumer.accept(e);}}}

异步任务回调 就是想让线程运行完成后执行其他线程设置的回调方法。
这里通过 thenSuccess 设置异步线程的回调方法 ,然后通过以下代码去判断是否已经设置了异步回调。

 if (successConsumer != null){successConsumer.accept(value);}

这里还有一个问题,主线程是先调用了run方法,再调用了thenSuccess方法,如果run方法和thenSuccess方法之前的执行时间超过了异步任务的执行时间。

在这里插入图片描述

避免这种问题的解决办法有2中。

  1. 在run之前先调用thenError 、thenSuccess 设置好回调后,再调用run。
    由于在开启线程之前就已经设置好回调了,自然不用担心。

  2. 在thenError、thenSuccess 方法内判断线程的状态,如果线程的isAlive方法返回false,则说明线程已经运行完了,在运行中的线程状态是true,所以,将线程的返回值以及异常保存起来,在调用 thenError、thenSuccess 方法 时,判断线程如果运行完成(调用了start方法的线程状态会是true),这个时候说明还没有执行回调,则拿到返回值后调用回调方法即可。

 if (this.thread != null && !this.thread.isAlive() && e == null){consumer.accept(value);}
  • 泛型

关于泛型的理解,泛型类可以想象成一个翁,翁就是一个容器,可以装各种各样的东西,每个翁都是如此,但是为了方便装的东西后续可以快速找到,就给每一个翁贴上一个标签,例如第一个翁只装钥匙,第二个翁只装杯子等等,这样从翁中拿出来的时候也只会是放进入的东西。泛型就相当于翁的一个标签,标识着此翁装配的东西,

一个翁也就是是带泛型的Java对象,在当作参数传递的过程中翁上的标签也是会传递的,Java编译器会自动检查带泛型的对象返回的类型以及当作参数传入的对象类型,例如 stream的map方法在使用lambda返回时 会自动推断返回值类型,如果接受的类型不匹配,编译器会报错,再比如使用lambda表达式定义入参时,无需指定参数类型,如果泛型类型是String类型,那就调不了其他类的方法,这也是有编译器保证的,这就是泛型的自动推断和传递。

有的实例方法需要的参数也是带着泛型的,例如AsyncTask中的

    public void thenSuccess(Consumer<T> consumer){this.successConsumer = consumer;if (this.thread != null && !this.thread.isAlive() && e == null){consumer.accept(value);}}public void thenError(Consumer<? super Exception> consumer){this.exConsumer = consumer;if (this.thread != null && !this.thread.isAlive() && e != null){consumer.accept(e);}}

例如thenSuccess 方法需要一个Consumer 实例,而这个实例也是需要带标签的,那这个标签是什么呢?就是取决于当前对象的标签,例如我有一个翁,标签是 钥匙,那我需要一个处置东西的工具、而这个处置东西的工具也可以打标签,例如可以处置杯子、处置木头、处置钥匙等,那这个地方的意思就是我需要一个Consumer类型的对象,这个对象的标签是T,而T是哪里来的,T是在创建当前对象的时候定义好的,也就是类似常说的出厂设置,这个实例在创建的时候就知道自己的泛型,即 某个翁在制造好出厂的时候就打好标签了。那自然 此对象在当作参数传递时,编译器也会自动检查标签是否与某个方法参数相匹配等等。

相关文章:

自定义封装异步任务组件,实现FutureTask功能

FutureTask 在 JDK1.8 后的异步编排API中的CompletableFuture&#xff0c;提供了 异步任务的成功回调、异常回调。 public class FutureTaskTest {public static void main(String[] args) throws Exception {CompletableFuture<String> future CompletableFuture.sup…...

【区块链 | IPFS】IPFS节点搭建、文件上传、节点存储空间设置、节点上传文件chunk设置

一、创建ipfs节点 通过ipfs init在本地计算机建立一个IPFS节点 本文有些命令已经执行过了&#xff0c;就没有重新初始化。部分图片拷贝自先前文档&#xff0c;具体信息应以实物为准 ipfs init initializing IPFS node at /Users/CHY/.ipfs generating 2048-bit RSA keypair.…...

【autodesk】浏览器中渲染rvt模型

使用Forge完成渲染 Forge是什么 为什么能够渲染出来rvt模型 Forge是由Autodesk开发的一套云端开发平台和工具集。在Forge平台中&#xff0c;有一个名为"Model Derivative"的服务&#xff0c;它可以将包括RVT&#xff08;Revit&#xff09;在内的多种BIM&#xff08…...

Python超入门(1)__迅速上手操作掌握Python

# 1.第一个代码&#xff1a;输出语句 # 1.第一个代码&#xff1a;输出语句 print("My dogs name is Huppy!") print(o----) print( ||| ) print("*" * 10) """ 输出结果&#xff1a; My dogs name is Huppy! o----||| ********** "&…...

后端面试话术集锦第 十四 篇:go语言面试话术

这是后端面试集锦第十四篇博文——go语言面试话术❗❗❗ 1. go数组、切片、扩容 go的数组和切片都是用来存储相同类型的数据集合。 数组是存储固定大小的集合,且为值引用。 但切片是存储无固定大小的集合,且为引用类型。 切片有三个属性,分别为指向指针的数组array,数组…...

Oralce集群管理-19C RAC 私有网络调整为BOND1

1 尝试在线添加私有网络的新接口 是否成功。 使用oifcfg命令在线添加新的网卡接口&#xff0c;在还没有配置bond1的条件下 也是可以添加成功的。 [gridorcldb1 ~]$ oifcfg getif eno3 192.168.224.0 global public ens3f0 10.2.0.0 global cluster_interconnect,asm eno…...

洛谷 Array 数论

题目&#xff1a; 对于长度为n的数组A&#xff0c;A中只包含从1到n的整数&#xff08;可重复&#xff09;。如果A单调不上升或单调不下降&#xff0c;A就可称为美丽的。 找出在长度为n时&#xff0c;有几个美丽的A。 思路&#xff1a; 这是一道数论题。 我们先找找“单调不递…...

简明SQL条件查询指南:掌握WHERE实现数据筛选

条件查询是用于从数据库中根据特定条件筛选数据行的一种方式&#xff0c;它避免了检索整个表中的数据。通常&#xff0c;使用 WHERE 子句来定义过滤条件&#xff0c;只有符合这些条件的数据行才会被返回。 SQL中的运算符有&#xff1a;、!、<、> 等&#xff0c;用于进行…...

通过HbaseClient来写Phoenix表实现

由于数据存储在Hbase上&#xff0c;并且上层使用了Phoenix来读写数据。并且由于数据的列字段不固定&#xff0c;并且可能由于Hbase表列和Phoenix的表列字段不一致&#xff0c;使用Phoenix写入的数据会导致写出报错的问题出现。所以这里直接使用HbaseClient写入到Hbase表中&…...

uniapp qiun charts H5使用echarts的eopts配置不生效

原因是&#xff1a;使用web的要设置 echartsH5 :echartsH5"true" <template><view class"charts-box"><view class"chart-title"> 趋势</view><qiun-data-chartstype"column":eopts"eopts":cha…...

嵌入式Linux驱动开发(LCD屏幕专题)(三)

1. 硬件相关的操作 LCD驱动程序的核心就是&#xff1a; 分配fb_info设置fb_info注册fb_info硬件相关的设置 硬件相关的设置又可以分为3部分&#xff1a; 引脚设置时钟设置LCD控制器设置 2. 在设备树里指定LCD参数 framebuffer-mylcd {compatible "100ask,lcd_drv&qu…...

MySQL视图用户管理

文章目录 视图视图的规则用户用户信息创建用户删除用户修改密码 用户权限给用户授权回收权限 视图 视图是一个虚拟表&#xff0c;其内容由查询定义。同真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表&#xff0c;基表的数据变化也会…...

我发现了一个很好看的字体,霞鹜文楷!如何换windows和typora字体?

1、字体 官方地址如下&#xff0c;下载也很简单。 https://github.com/lxgw/LxgwWenKai 有1W多的stars。 方式&#xff1a; 直接打包下载。下载不来&#xff0c;可以联系我。 然后ttf的文件&#xff0c;全部安装就行了。 reg save "HKCU\Control Panel" .\res…...

微软8月系统更新引发问题:虚拟内存分页文件出现错误

微软的八月系统更新引发了一系列问题&#xff0c;其中包括“UNSUPPORTED_PROCESSOR”蓝屏错误和文件管理器故障。尽管微软已经修复了前者&#xff0c;但据国外科技媒体Windows Latest报道&#xff0c;仍有用户反馈在非微星设备上出现“fault in nonpaged area”蓝屏错误。 如果…...

swiper删除虚拟slide问题

在存在缓存的情况下&#xff0c;删除较前的slide&#xff0c;会出现当前slide与后一个slide重复出现的情况 假设当前存在5个slide&#xff0c;且这5个slide已缓存&#xff0c;则删除slide2后&#xff0c;仍为5个slide&#xff0c;且slide2的内容变为slide3的内容&#xff0c;此…...

FPGA实战小项目2

基于FPGA的贪吃蛇游戏 基于FPGA的贪吃蛇游戏 基于fpga的数字密码锁ego1 基于fpga的数字密码锁ego1 基于fpga的数字时钟 basys3 基于fpga的数字时钟 basys3...

一些关于完整小程序项目的优秀开源

转载自&#xff1a; 35个项目&#xff0c;开源&#xff0c;开源&#xff01; (qq.com) 那几本霸占我休息时间的PDF&#xff01; (qq.com) 13个超强的 SpringBoot 实战项目 &#xff08;还不赶紧收藏起来&#xff09; (qq.com) 用SpringBoot开发一个人脸识别系统&#xff01…...

Windows模拟器推荐

物是人非事事休&#xff0c;欲语泪先流 Windows模拟器推荐 如果你需要在 Windows 操作系统之外运行 Windows 应用程序或测试不同版本的 Windows&#xff0c;有几个 Windows 模拟器和虚拟机软件可供选择。以下是一些常用的 Windows 模拟器和虚拟机软件&#xff1a; VirtualBox&…...

搭建RabbitMQ消息服务,整合SpringBoot实现收发消息

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;3年JAVA全栈开发经验&#xff0c;专注JAVA技术、系统定制、远程指导&#xff0c;致力于企业数字化转型&#xff0c;CSDN博客专家&#xff0c;蓝桥云课认证讲师。 目录 一、前言1.1 什么是消息队列1.2 RabbitMQ 是什么1.…...

Web framework-Gin(二)

目录 一、Gin 1、Ajax 2、文件上传 2.1、form表单中文件上传(单个文件) 2.2、form表单中文件上传(多个文件) 2.3、ajax上传单个文件 2.4、ajax上传多个文件 3、模板语法 4、数据绑定 5、路由组 6、中间件 一、Gin 1、Ajax AJAX 即“Asynchronous Javascript And XM…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...