java中的Future的设计模式 手写一个简易的Future

案例

例如:今天是小妹的生日,需要一个蛋糕有点仪式感,于是去蛋糕店预定,预定完之后,店老板说蛋糕做好了,到时电话通知你,不可能在这傻傻的等着吧,还有其他事情要做啊,于是我的去做其他事情,等老板电话后再来取蛋糕。这样可以充分利用自己的时间去赚钱,如果用这个案例写一个Java代码 如何实现,

Future的理解和用途

Future是个未来的事情,相当与一个票据,或者可以理解是一个凭证,用这个凭证去获取所需要的结果,

代码的逻辑解析

SimpleFuture —>代表未来的一个凭据
SimpleFutureTask —>将你的调用逻辑进行隔离封装
SimpleFutureService —> 桥接Future和FutureTask
这是一种很好的设计模式 SimpleFuture 不需要知道 SimpleFutureTask的存在,而SimpleFutureTask也不需要知道SimpleFuture 的存在,只要SimpleFutureService 需要知道他们两者的存在,而对于调用者而言,只要知道SimpleFutureService 就行,我们将业务逻辑封装成一个task模式,并且返回一个SimpleFuture

简单的Future凭证接口

1、get方法
获取任务结束后返回的结果,如果调用时,任务还没有结束,则会进行阻塞线程,直到任务完成。该阻塞是可以被打断的,打断的线程是调用get方法的线程,被打断后原任务会依旧继续执行。

/*** SimpleFuture接口定义了一个简单的异步计算的结果获取方法* 它提供了一种机制来获取异步任务的结果,如果任务尚未完成,则调用get方法的线程会被阻塞,* 直到计算完成并且结果可用* * @param <T> 表示异步计算结果的类型*/
public interface SimpleFuture<T> {/*** 获取异步计算的结果如果计算尚未完成,则此方法会阻塞,直到计算完成* 如果计算过程中遇到中断,此方法会抛出InterruptedException* * @return 异步计算的结果* @throws InterruptedException 如果调用get方法的线程在等待计算完成时被中断*/T get() throws InterruptedException;
}

获取任务的结果

/*** SimpleFutureTask接口定义了一个异步任务的标准.* 它代表了一个将会在将来执行的任务,并且该任务有一个结果.* 这个接口的主要用途是为那些想要实现异步执行并返回结果的任务提供一个统一的标准.** @param <T> 表示任务返回结果的类型.*/
public interface SimpleFutureTask<T> {/*** 执行异步任务并返回结果.* 该方法将在某个时刻被调用,以期望异步地完成任务并返回结果.* * @return 任务的结果,类型为泛型T.*/T call();
}

实现SimpleFuture的接口

/*** AsynSimpleFuture 类实现了一个异步操作的简单未来对象* 它允许在一个线程中设置结果,在另一个线程中获取结果* 主要用于线程间通信,以异步方式处理任务的结果** @param <T> 未来操作结果的类型*/
public class AsynSimpleFuture<T> implements SimpleFuture<T>{// 标记任务是否完成,volatile 关键字确保多线程环境下的可见性private volatile boolean finished = false;// 存储任务的结果private T result;/*** 当任务完成时调用此方法,它会设置结果值并通知所有等待的线程** @param result 任务的结果*/public void finish(T result){synchronized (this){this.result = result;this.finished = true;this.notifyAll();}}/*** 获取任务的结果如果任务未完成,当前线程会等待直到任务完成** @return 任务的结果* @throws InterruptedException 如果在等待过程中线程被中断*/@Overridepublic T get() throws InterruptedException {synchronized (this){while (!finished){this.wait();}}return result;}
}

将SimpleFutureTask和 SimpleFutureTask 或 AsynSimpleFuture联系起来

/*** SimpleFutureService类提供了异步执行任务的功能* 它通过管理线程来执行提交的任务,并返回一个表示异步计算结果的AsynSimpleFuture对象*/
public class SimpleFutureService {/*** 提交一个SimpleFutureTask任务进行异步执行* 该方法的返回值可以为 SimpleFuture<T>* @param task 要异步执行的任务,它实现了call方法来定义任务的具体执行逻辑* @return 返回一个AsynSimpleFuture对象,通过它可以获取任务执行结果* * 此方法创建并启动一个新的线程来执行给定的任务任务的执行结果会被封装在这个AsynSimpleFuture对象中* 使用者可以使用这个对象来获取任务执行结果,而无需阻塞当前线程*/public <T> AsynSimpleFuture<T> submit(SimpleFutureTask<T> task, Consumer<T> consumer) {AsynSimpleFuture<T> future = new AsynSimpleFuture<>();new Thread(() -> {T result = task.call();future.finish(result);consumer.accept(result);}).start();return future;}
}

测试一下代码的效果

/*** SyncInvoker 类用于演示如何使用 SimpleFutureService 来执行异步任务并在任务完成后获取结果*/
public class SyncInvoker {/*** 主函数执行异步任务并展示执行结果* @param args 命令行参数* @throws InterruptedException 如果在睡眠期间线程被中断*/public static void main(String[] args) throws InterruptedException {// 创建 SimpleFutureService 实例SimpleFutureService simpleFutureService = new SimpleFutureService();// 提交异步任务并获取未来结果simpleFutureService.submit(SyncInvoker::bookAndPickUpCake,System.out::println);Optional.of("-----*************-------").ifPresent(System.out::println);// 应该是在获取结果之前,先执行其他任务Optional.of("-----go to work-------").ifPresent(System.out::println);// 模拟其他任务的耗时Thread.sleep(5000);Optional.of("-----I finish my work -------").ifPresent(System.out::println);Optional.of("-----####去蛋糕店等待或等待老板电话或老板送货上面#####-------").ifPresent(System.out::println);}/*** 模拟一个耗时的异步任务,例如预订并取回蛋糕* @return 任务结果,在这个例子中是蛋糕的名称*/private static String bookAndPickUpCake() {try {// 模拟耗时操作Thread.sleep(10000);return "BIRTHDAY CAKE";} catch (InterruptedException e) {throw new RuntimeException(e);}}
}执行的结果:
-----*************-------
-----go to work-------
-----I finish my work -------
-----####等待老板电话或老板送货上面#####-------
BIRTHDAY CAKE

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/79159.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Redis】Redis C++使用

一、Redis的自定义网络协议 1.1 为什么可以编写出一个自定义的Redis客户端 为什么我们可以编写出一个自定义的Redis客户端&#xff1f;因为Redis公开了自己的自定义协议。而对于一些其他软件的客户端&#xff0c;我们无法编写出一个自定义的Redis客户端&#xff0c;因为他们没…

【软考系统架构设计师】软件工程知识点

1、 软件开发生命周期 软件定义时期&#xff1a;包括可行性研究和详细需求分析过程&#xff0c;任务是确定软件开发工程必须完成的总目标&#xff0c;具体分为问题定义、可行性研究、需求分析等 软件开发时期&#xff1a;软件的设计与实现&#xff0c;分为概要设计、详细设计、…

DeepSeek 与开源:肥沃土壤孕育 AI 硕果

当国产 AI DeepSeek 以其低成本推理和多模态能力在全球范围内引起轰动时&#xff0c;人们惊叹于中国技术的迅猛发展&#xff0c;却很少有人深究这一成就背后的根基。答案其实早已写在中国开源生态二十多年的发展历程中。 从倪光南院士提出“以开源打破技术垄断”的理念&#x…

职坐标:智慧城市未来发展的核心驱动力

内容概要 智慧城市的演进正以颠覆性创新重构人类生存空间&#xff0c;其发展脉络由物联网、人工智能与云计算三大技术支柱交织而成。这些技术不仅推动城市治理从经验决策转向数据驱动模式&#xff0c;更通过实时感知与智能分析&#xff0c;实现交通、能源等领域的精准调控。以…

vue复习46~90

1.小兔鲜 所有都折叠 ctrl k,ctrl0 所有都展开 ctrl k,ctrlj当前结构渲染5次 <BaseBrandItem v-for"item in 5" :key"item"><BaseBrandItem>2.scoped样式冲突 结构&#xff1a;只能有一个根元素样式&#xff1a;全局样式(默认)&#xff1…

PHP 用 workman 即时通讯,做个简版QQ

1. workman是什么 &#xff0c;一般应用在那些地方 workerman是一个高性能的PHP socket 服务器框架&#xff0c;workerman基于PHP多进程以及libevent事件轮询库&#xff0c;PHP开发者只要实现一两个接口&#xff0c;便可以开发出自己的网络应用&#xff0c;例如Rpc服务、聊天室…

【WORD】批量将doc转为docx

具体步骤进行&#xff1a; 打开Word文档&#xff0c;按下AltF11快捷键&#xff0c;打开VBA编辑器。在VBA编辑器中&#xff0c;左侧的“项目资源管理器”窗口会显示当前打开的Word文档相关项目。找到您要添加代码的文档项目&#xff08;通常以文档名称命名&#xff09;&#xf…

【免费】【实测有用】5KPlayer Windows 电脑作为 MacBook 无线扩展屏

总结&#xff1a;使用 5KPlayer 将 Windows 电脑作为 MacBook 无线扩展屏 准备工作 设备要求&#xff1a; MacBook 和 Windows 电脑需连接到同一 Wi-Fi 网络。【这里有雷&#xff1a;eduroam不会成功&#xff0c;家里的WIFI成功了&#xff0c;需要确认校园网是否可行。】确保…

华为华三模拟器解决兼容问题Win11 24H2 现在使用ENSP的问题解决了

一、Win11 24H2 现在使用ENSP的问题解决了 这个Win11 的 24H2不能使用ENSP的问题已经困扰我们很久了,在之前的文章中,我们也有说明这个问题 之前ENSP肯定启动会报错40 当时还建议大家先不要更新到win11的24H2版本,现在终于迎来了更新,不用再担心了,包括早就升级了24H2版…

嵌入式WebRTC轻量化SDK压缩至500K-800K ,为嵌入式设备节省Flash资源

一、SDK轻量化的核心技术实现 1、WebRTC库裁剪与模块化设计 EasyRTC针对嵌入式设备的资源限制&#xff0c;对原生WebRTC库进行深度裁剪&#xff0c;仅保留核心通信功能&#xff08;如信令管理、编解码、网络传输等&#xff09;&#xff0c;移除冗余组件&#xff08;如部分调试…

Maya云渲染工作流,提升渲染速度

在三维动画与影视特效领域&#xff0c;Autodesk Maya作为行业标杆工具&#xff0c;承载着从角色建模到复杂特效渲染的全流程创作。然而&#xff0c;本地硬件性能不足、渲染周期漫长、跨团队协作效率低等痛点始终困扰着创作者。渲染101云渲染以弹性算力资源、智能化工作流与全方…

git怎么使远程分支回退到指定的节点处

git使远程分支回退到指定的节点 引言场景描述步骤 引言 最近提交代码的时候&#xff0c;总将分支合并错&#xff0c;原本要合到A分支&#xff0c;结果合并到了B分支&#xff0c;这样就导致b分支需要回退到我没有合并之前的节点处。 本文记录下怎么将远程分支回退到指定的节点。…

全网通emotn ui桌面免费吗?如何开机自启动

在智能设备的使用中&#xff0c;一款优秀的桌面系统能带来截然不同的体验。全网通Emotn UI桌面便是其中的佼佼者&#xff0c;它以完全免费的特性与卓越性能&#xff0c;成为众多用户的心头好。 其简洁美观的界面设计如同为设备换上"清新外衣"&#xff0c;常用功能一…

通过微信APPID获取小程序名称

进入微信公众平台&#xff0c;登录自己的小程序后台管理端&#xff0c;在“账号设置”中找到“第三方设置” 在“第三方设置”页面中&#xff0c;将页面拉到最下面&#xff0c;即可通过appid获取到这个小程序的名称信息

2025年第十六届蓝桥杯省赛JavaB组真题回顾

第16届蓝桥杯省赛已经结束了&#xff0c;第一次参加也是坐牢了4个小时&#xff0c;现在还是来总结一下吧&#xff08;先声明以下的解法&#xff0c;大家可以当作一种思路来看&#xff0c;解法不一定是正解&#xff0c;只是给大家提供一种能够正常想到的思路吧&#xff09; 试题…

深入剖析 Axios 的 POST 请求:何时使用 qs 处理数据

在前端开发中&#xff0c;Axios 是一个广泛使用的用于发送 HTTP 请求的库&#xff0c;特别是在处理 POST 请求时&#xff0c;数据的处理方式会直接影响到请求能否正确被后端接收和处理。其中&#xff0c;使用 qs 库对数据进行处理是一个常见的操作点&#xff0c;本文将深入探讨…

通过websocket给服务端发送订单催单提醒消息

controller层 GetMapping("/reminder/{id}")public Result Remainder(PathVariable("id") Long id){orderService.remainder(id);return Result.success();} 实现类 Overridepublic void remainder(Long id) {Orders ordersDB orderMapper.getById(id);…

ros_note02

note02 节点 ROS2中每一个节点只负责一个单独的模块化功能 如&#xff1a;一个节点负责控制车轮转动&#xff0c;一个节点负责从激光雷达获取数据&#xff0c;一个节点负责定位 通信方式&#xff1a; 话题&#xff1a;topic服务&#xff1a;services动作&#xff1a;Actio…

使用治疗前MR图像预测脑膜瘤Ki-67的多模态深度学习模型

大家好&#xff0c;我是带我去滑雪&#xff01; 脑膜瘤是一种常见的脑部肿瘤&#xff0c;Ki-67作为肿瘤细胞增殖的标志物&#xff0c;对于评估肿瘤的生物学行为、预后以及治疗方案的制定具有至关重要的作用。然而&#xff0c;传统的Ki-67检测依赖于组织学切片和免疫组化染色等方…

【大模型系列篇】深度研究智能体技术演进:从DeepResearch到DeepResearcher,如何重构AI研究范式

DeepResearch 的概念与功能最早由 Google 在 Gemini 系列产品中推出&#xff0c;用于自动化生成结构化研究报告&#xff0c;近期底层依赖模型Gemini升级到了2.5 Pro。而我们常规认知的DeepResearch是由OpenAI推出的一款由优化版的 o3 模型驱动专注于深度研究和分析的AI智能体产…