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

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

相关文章:

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

案例 例如&#xff1a;今天是小妹的生日&#xff0c;需要一个蛋糕有点仪式感&#xff0c;于是去蛋糕店预定&#xff0c;预定完之后&#xff0c;店老板说蛋糕做好了&#xff0c;到时电话通知你&#xff0c;不可能在这傻傻的等着吧&#xff0c;还有其他事情要做啊&#xff0c;于…...

USB(TYPE-C)转串口(TTL)模块设计讲解

目录 一 、引言 二、方案设计 三、USB TYPE-C介绍 1、TYPE-C接口定义 1、24P全引脚描述 2、Type C 接口 VBUS/GND 作用 3、Type C 接口 D/D- 作用 1、数据传输&#xff1a; 2、设备识别&#xff1a; 3、充电协议协商&#xff1a; 4、Type C 接口 CC1/CC2 作用 1、主从设备区…...

JavaScript | ajax实现原理

在早期&#xff0c;web应用&#xff0c;更多采用mvc框架&#xff0c;通过后端输出整个页面的内容&#xff0c;然后再用浏览器进行渲染&#xff0c;这样效率不高&#xff0c;对于事件绑定来说比较麻烦&#xff0c;于是提出了ajax&#xff0c;其最大的特点就是能实现局部更新。通…...

PyTorch张量操作指南:cat、stack、split与chunk的实战拆解

本文深入探讨PyTorch中用于调整张量结构的四个核心函数——torch.cat、torch.stack、torch.split和torch.chunk。通过实际应用场景分析和代码演示&#xff0c;帮助读者掌握它们的功能差异及适用条件&#xff0c;提升模型开发的灵活性与效率。 在深度学习实践中&#xff0c;张量…...

YOLO涨点技巧之分层扩展路径聚合网络 (HEPAN)

一、应用场景与问题背景 1.1 无人机图像检测挑战 https://ai-studio-static-online.cdn.bcebos.com/3d4f7e8c4d8d4d2d8a4c8e4b4e8c4d8d ​场景特点:无人机航拍视角下的小目标检测(如行人、车辆、农作物病害等)​核心难点: 目标尺寸小(<3232像素)复杂背景干扰(如城市…...

SQLite、MySQL、SQL Server、Oracle 和 PostgreSQL 五种数据库的区别

以下是 SQLite、MySQL、SQL Server、Oracle 和 PostgreSQL 五种主流关系型数据库管理系统(RDBMS)的区别,从多个维度进行对比: 1. 架构与部署 SQLite(Structured Query Language Lite‌): 嵌入式数据库,无服务器架构。数据库存储在一个单一的磁盘文件中。部署简单,适合轻量…...

git在分支上会退到某个指定的commit

1、在idea上先备份好分支&#xff08;基于现有分支new branch&#xff09; 2、在gitlab管理端删除现有分支 3、在idea中大卡terminal&#xff0c;执行 git log 查看commit log ,找到要会退到的commit唯一码&#xff0c;然后执行git reset 唯一码 4、查看本地代码状态 git st…...

玩机进阶教程----MTK芯片设备刷机导致的死砖修复实例解析 连电脑毫无反应 非硬件问题

在高通芯片机型中,我们可以通过短接主板测试点来激活高通芯片特有的9008底层端口来刷写救砖固件。但通常MTK芯片类的设备联机电脑即可触发深刷模式。但有些例外的情况会导致链接电脑毫无反应。遇到类似故障的友友可以参阅此博文尝试解决。 通过博文了解 1💝💝💝-----实…...

MIPI协议介绍

MIPI协议介绍 mipi 协议分为 CSI 和DSI,两者的区别在于 CSI用于接收sensor数据流 DSI用于连接显示屏 csi分类 csi 分为 csi2 和 csi3 csi2根据物理层分为 c-phy 和 d-phy, csi-3采用的是m-phy 一般采用csi2 c-phy 和 d-phy的区别 d-phy的时钟线和数据线是分开的,2根线一对…...

MySQL 中 `${}` 和 `#{}` 占位符详解及面试高频考点

文章目录 一、概述二、#{} 和 ${} 的核心区别1. 底层机制代码示例 2. 核心区别总结 三、为什么表名只能用 ${}&#xff1f;1. 预编译机制的限制2. 动态表名的实现 四、安全性注意事项1. ${} 的风险场景2. 安全实践 五、面试高频考点1. 基础原理类问题**问题 1**&#xff1a;**问…...

AI应用开发平台 和 通用自动化工作流工具 的详细对比,涵盖定义、核心功能、典型工具、适用场景及优缺点分析

以下是 AI应用开发平台 和 通用自动化工作流工具 的详细对比&#xff0c;涵盖定义、核心功能、典型工具、适用场景及优缺点分析&#xff1a; 1. AI应用开发平台 vs 通用自动化工作流工具 (1) 定义与目标 类型AI应用开发平台通用自动化工作流工具定义用于快速构建、训练、部署…...

GitHub 趋势日报 (2025年04月12日)

本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ &#x1f4c8; 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1yeongpin/cursor-free-vip[Support 0.48.x]&#xff08;Reset Cursor AI MachineID & Auto Sign Up / In & Bypass Higher…...

asm汇编源代码之-字库转换程序

将标准的16x16点阵汉字库(下载16x16汉字库)转换成适合VGA文本模式下显示的点阵汉字库 本程序需要调用file.asm中的子程序,所以连接时需要把file连接进来,如下 C:\> tlink chghzk file 调用参数描述如下 C:\> chghzk ; 无调用参数,转换标准库文件(SRC16.FNT)为适合VGA…...

VMware Ubuntu挂载Windows机器的共享文件

https://www.dong-blog.fun/post/2029 在VMware Ubuntu中访问Windows共享文件夹&#xff1a;完整指南 在使用VMware运行Ubuntu虚拟机时&#xff0c;访问Windows主机上的文件是常见需求。本文将详细介绍如何通过网络共享方式&#xff0c;让Ubuntu虚拟机直接访问Windows主机的文…...

智慧社区数据可视化中枢平台——Axure全场景交互式大屏解决方案

在数字化治理的时代浪潮中&#xff0c;社区管理正面临数据碎片化、响应滞后、决策盲区等核心挑战。如何将分散的安防、环境、能源、民生服务等数据整合为可操作的智慧洞察&#xff1f;如何让冰冷的数字转化为社区管理者手中的决策利器&#xff1f;Axure智慧社区可视化大屏原型模…...

Axure高保真AI算法训练平台

点击下载《Axure高保真AI算法训练平台(.rp) 》 原型效果&#xff1a;https://axhub.im/ax9/69fdf8f2b10b59c3/#g1 摘要 本文介绍了一款功能全面且高效的AI算法训练平台&#xff0c;旨在为数据科学家、研究人员和工程师提供从数据准备到模型部署的一站式解决方案。该平台由四大…...

C++ Json-Rpc框架-3项目实现(2)

一.消息分发Dispatcher实现 Dispatcher 就是“消息分发中枢”&#xff1a;根据消息类型 MType&#xff0c;把消息派发给对应的处理函数&#xff08;Handler&#xff09;执行。 初版&#xff1a; #pragma once #include "net.hpp" #include "message.hpp"n…...

youtube视频和telegram视频加载原理差异分析

1. 客户侧缓存与流式播放机制​​ 流式视频应用&#xff08;如 Netflix、YouTube&#xff09;通过​​边下载边播放​​实现流畅体验&#xff0c;其核心依赖以下技术&#xff1a; ​​缓存预加载​​&#xff1a;客户端在后台持续下载视频片段&#xff08;如 DASH/HLS 协议的…...

LLM小白自学笔记:1.两种指令微调

一、LoRA 简单来说&#xff0c;LoRA不直接调整个大模型的全部参数&#xff08;那样太费资源&#xff09;&#xff0c;而是在模型的某些层&#xff08;通常是注意力层&#xff09;加个“旁路”——两个小的矩阵&#xff08;低秩矩阵&#xff09;。训练时只更新这俩小矩阵&#x…...

【NLP】 19. Tokenlisation 分词 BPE, WordPiece, Unigram/SentencePiece

1. 翻译系统性能评价方法 在机器翻译系统性能评估中&#xff0c;通常既有人工评价也有自动评价方法&#xff1a; 1.1 人工评价 人工评价主要关注以下几点&#xff1a; 流利度&#xff08;Fluency&#xff09;&#xff1a; 判断翻译结果是否符合目标语言的语法和习惯。充分性…...

OpenAI发布GPT-4.1系列模型——开发者可免费使用

OpenAI刚刚推出GPT-4.1模型家族&#xff0c;包含GPT-4.1、GPT-4.1 Mini和GPT-4.1 Nano三款模型。重点是——现在全部免费开放&#xff01; 虽然技术升级值得关注&#xff0c;但真正具有变革意义的是开发者能通过Cursor、Windsurf和GitHub Copilot等平台立即免费调用这些模型。…...

各地物价和生活成本 东欧篇

东欧地区的物价差异相对较大&#xff0c;一些国家的物价较高&#xff0c;而另一些国家则相对便宜。这些差异主要受当地经济发展水平、工资水平、旅游业发展以及国际关系等因素影响。以下是一些典型的东欧国家&#xff0c;按物价高低进行分类&#xff1a; &#x1f30d; 物价较高…...

Vue —— 实用的工具函数

目录 响应式数据管理1. toRef 和 torefs2. shallowRef 和 shallowReactive3. markRaw 依赖追踪与副作用1. computed2. watch 和 watchEffect 类型判断与优化1. unref2. isRef 、isReactive 和 isProxy 组件通信与生命周期1. provide 和 inject2. nextTick 高级工具1. useAttrs …...

flex布局(笔记)

弹性布局&#xff08;Flex布局&#xff09;是一种现代的CSS布局方式&#xff0c;通过使用display: flex属性来创建一个弹性容器&#xff0c;并在其中使用灵活的盒子模型来进行元素的排列和定位。 主轴与交叉轴&#xff1a;弹性容器具有主轴&#xff08;main axis&#xff09;和…...

第二阶段:数据结构与函数

模块4&#xff1a;常用数据结构 (Organizing Lots of Data) 在前面的模块中&#xff0c;我们学习了如何使用变量来存储单个数据&#xff0c;比如一个数字、一个名字或一个布尔值。但很多时候&#xff0c;我们需要处理一组相关的数据&#xff0c;比如班级里所有学生的名字、一本…...

云函数采集架构:Serverless模式下的动态IP与冷启动优化

在 Serverless 架构中使用云函数进行网页数据采集&#xff0c;不仅能大幅降低运维成本&#xff0c;还能根据任务负载动态扩展。然而&#xff0c;由于云函数的无状态特性及冷启动问题&#xff0c;加上目标网站对采集行为的反制措施&#xff08;如 IP 限制、Cookie 校验等&#x…...

Linux笔记---动静态库(原理篇)

1. ELF文件格式 动静态库文件的构成是什么样的呢&#xff1f;或者说二者的内容是什么&#xff1f; 实际上&#xff0c;可执行文件&#xff0c;目标文件&#xff0c;静态库文件&#xff0c;动态库文件都是使用ELF文件格式进行组织的。 ELF&#xff08;Executable and Linkable…...

string的模拟实现 (6)

目录 1.string.h 2.string.cpp 3.test.cpp 4.一些注意点 本篇博客就学习下如何模拟实现简易版的string类&#xff0c;学好string类后面学习其他容器也会更轻松些。 代码实现如下&#xff1a; 1.string.h #define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include <…...

【野火模型】利用深度神经网络替代 ELMv1 野火参数化:机制、实现与性能评估

目录 一、ELMv1 野火过程表示法&#xff08;BASE-Fire&#xff09;关键机制野火模拟的核心过程 二、采用神经网络模拟野火过程三、总结参考 一、ELMv1 野火过程表示法&#xff08;BASE-Fire&#xff09; ELMv1 中的野火模型&#xff08;称为 BASE-Fire&#xff09;源自 Commun…...

红宝书第四十七讲:Node.js服务器框架解析:Express vs Koa 完全指南

红宝书第四十七讲&#xff1a;Node.js服务器框架解析&#xff1a;Express vs Koa 完全指南 资料取自《JavaScript高级程序设计&#xff08;第5版&#xff09;》。 查看总目录&#xff1a;红宝书学习大纲 一、框架定位&#xff1a;HTTP服务器的工具箱 共同功能&#xff1a; 快…...