【手摸手】教你实现自己的 Java Future

华为OD机试真题 2026.11.4. 新系统 【河流水系流量评估】 华为OD机试真题 新系统【河流水系流量评估】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【河流水系流量评估】多语言题解。 阅读详情

【追女神】VS Java Future

你是一位痴情的程序员(主线程),你有一位喜欢的女神(任务目标)。
你终于鼓起勇气,发了条微信表白:“小美,其实,我喜欢你很久了,你可以做我女朋友吗?”(提交任务,等待女神回复)。
你知道她可能不会立刻回复,于是你继续敲代码、改bug。(主线程继续干活)。
你忐忑不安,你偶尔偷瞄手机看看有没有回复。(isDone()检查任务状态)。
你迫不及待,点开女神的聊天界面等待回复消息(get())。

接下来可能会有一下几种情况发生:

  1. 女神说喜欢你:你收获爱情(任务成功)
  2. 女神说你是好人但不合适:表白失败(任务异常)
  3. 女神被别人追到手,被截胡。(任务中断)
  4. 女神太久不回你?你决定放弃:不打算做舔狗了。(任务超时超时 or 取消)
追女神**Java Future **
给女神发表白微信提交异步任务(Callable)
她正在思考中(读消息)后台线程处理任务
你继续做自己的事,写代码或者看短剧主线程不阻塞
偷看手机,查看女神状态future.isDone()
打开聊天界面等待女神回复future.get()
女神同意了,表白成功,抱得美人归成功获取结果
女神拒绝了,表白失败抛出 ExecutionException
女神超过你等待时长,你不想等了TimeoutException
你点击“撤回表白”future.cancel(true)

需求设计:Future 要实现什么功能?

功能点拆解:

功能方法设计
提交任务异步执行submit(task)
阻塞等待结果get()方法
支持超时等待get(timeout)
支持取消任务cancel()
抛出异常get()中处理异常
可检查状态isDone()、isCancelled()

Future 接口是怎么设计的?

public interface Future<V> {
    //阻塞拿结果
    V get() throws InterruptedException, ExecutionException;
    //限时等待结果,超时抛出异常
    V get(long timeout, TimeUnit unit) throws ...;
    //尝试终止任务,只是一种通知
    boolean cancel(boolean mayInterruptIfRunning);
    //任务是否取消
    boolean isCancelled();
    //任务是否完成,正常完成、取消、异常都算完成
    boolean isDone();
}

自己动手实现 MyFutureTask

package com.omy.concurrent.fucture;

import java.util.Objects;
import java.util.concurrent.*;

public class MyFutureTask<V> implements Runnable, Future<V> {

    private Callable<V> callable;
    private V result;
    private Throwable exception;
    private Thread runner;
    private volatile boolean done;
    private volatile boolean canceled;
    private final Object lock = new Object();

    public boolean isCanceled() {
        return canceled;
    }

    public MyFutureTask(Callable<V> callable) {
        Objects.requireNonNull(callable, "Callable cannot be null")
        this.callable = callable;
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        synchronized (lock) {
            if (isDone() || isCanceled()) {
                return false;
            }
            canceled = true;
            done = true;
            if (mayInterruptIfRunning) {
                Thread t = runner;
                if (t != null) {
                    t.interrupt();
                }
            }
            lock.notifyAll();
            return true;
        }
    }

    @Override
    public boolean isCancelled() {
        return canceled;
    }

    @Override
    public boolean isDone() {
        return done;
    }

    @Override
    public V get() throws InterruptedException, ExecutionException {
        synchronized (lock) {
            while (!isDone() && !isCanceled()) {
                lock.wait();
            }
            if (isCanceled()) {
                throw new IllegalStateException("Task is cancelled");
            }
            if (exception != null) {
                throw new ExecutionException("Task failed", exception);
            }
            return result;
        }
    }

    @Override
    public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        if (timeout <= 0 || unit == null) {
            throw new IllegalArgumentException("Timeout and unit must be valid");
        }
        long deadline = System.nanoTime() + unit.toNanos(timeout);
        synchronized (lock) {
            while (!isDone() && !isCanceled()) {
                long remaining = deadline - System.nanoTime();
                if (remaining <= 0L) {
                    throw new TimeoutException("Task timeout");
                }
                long millis = remaining / 1_000_000L;
                int nanos = (int) (remaining % 1_000_000L);
                try {
                    lock.wait(millis, nanos);
                } catch (InterruptedException e) {
                    if (isCanceled()) {
                        throw new IllegalStateException("Task is cancelled");
                    }
                    throw e;
                }
            }
            if (isCanceled()) {
                throw new IllegalStateException("Task is cancelled");
            }
            if (exception != null) {
                throw new ExecutionException("Task failed", exception);
            }
            return result;
        }
    }

    @Override
    public void run() {
        synchronized (lock) {
            runner = Thread.currentThread();
            if (canceled) {
                return;
            }
        }
        try {
            V ret = callable.call();
            synchronized (lock) {
                done = true;
                result = ret;
                exception = null;
                lock.notifyAll();
            }
        } catch (Throwable ex) {
            synchronized (lock) {
                done = true;
                result = null;
                exception = ex;
                lock.notifyAll();
            }
        } finally {
            synchronized (lock) {
                runner = null;
            }
        }
    }
}

package com.omy.concurrent.fucture;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

@Slf4j
public class FutureDemo  {

    static class Xiao3 extends Thread{
        Thread thread;

        public Xiao3(Thread thread) {
            Thread.currentThread().setName("小三");
            this.thread = thread;
        }

        @Override
        public void run(){
            log.info("小三插足,女神被截胡了");
            thread.interrupt();
        }

    }

    public static void main(String[] args) {

        Callable<String> callable = () -> {
            while (!Thread.currentThread().isInterrupted()) {
                for (int i = 0; i < 3; i++) {
                    log.info("女神思考中...");
                    TimeUnit.SECONDS.sleep(1);
                }
                break;
            }
            return "我也喜欢你";
        };

        MyFutureTask<String> futureTask = new MyFutureTask<>(callable);
        Thread girlThread = new Thread(futureTask, "女神");
        girlThread.start();

        Thread.currentThread().setName("小帅");
        try {
            String result = futureTask.get(5, TimeUnit.SECONDS);
            log.info("女神同意,表白成功:{}", result);
        } catch (InterruptedException e) {
            log.error("表白被截胡,表白中断", e);
        } catch (ExecutionException e) {
            log.error("女神拒绝,表白被拒", e);
        } catch (TimeoutException e) {
            log.error("表白超时", e);
        }
        log.info("表白结束");
    }
}

SpringBoot+Vue+MySQL 高校学科竞赛平台 完整可运行版(源码+文档) 本项目基于SpringBoot+Vue+MySQL构建高校学科竞赛管理平台,覆盖学生、教师、领队教师、管理员四大角色,实现竞赛发布、报名、刷题、评分、公示等全流程闭环管理。系统架构清晰,技术主流,配套完整源码、数据库脚本、万字论文、开题报告、答辩PPT及部署文档,支持一键运行,适用于毕业设计、课程设计及院系二次开发,真正实现“开箱即用”。 阅读详情

相关推荐

电流采样(分流器与霍尔传感器)

霍尔效应霍尔效应是磁电效应的一种,这一现象是霍尔(A.H.Hall,1855—1938)于1879年在研究金属的导电机构时发现的。霍尔效应是研究半导体材料性能的基本方法。通过霍尔效应实验测定的霍尔系数,能够判断半导体材料的导电类型、载流子浓度及载流子迁移率等重要参数。简单原理如图1所示,半导体薄片两端通以控制电流I,垂直方向施加磁感应强度为B的匀强磁场,d为半导体材料的厚度,k为霍尔常数,它与半导体材质有关,则在垂直于电流和磁场的方向上,将产生电势差为UH的霍尔电压,它们之间的关系为。霍尔元件。

weixin_48867130的博客 1万+

接口响应慢?那是你没用 CompletableFuture 来优化!

来源|blog.youkuaiyun.com/qq_43372633/article/details/130814200???? 欢迎加入小哈的星球,你将获得:专属的项目实战 / Java 学习路线 /一对一提问 / 学习打卡 / 赠书福利全栈前后端分离博客项目 1.0 版本完结啦,2.0 正在更新中...,演示链接:http://116.62.199.48/,全程手摸手,后端 + 前端全栈开发,从 0...

犬小哈 195

Linux 命令之 localectl -- 控制系统的本地化与键盘布局

文章目录命令介绍常用选项参考示例(一)显示当前的本地化设置与键盘映射(二)设置系统的本地化字符集环境变量(三)列出本地所有字符集(四)列出所有可用的控制台键盘映射(五)设置控制台的键盘映射 命令介绍 localectl 命令可用于查询与修改系统的本地化(locale)与键盘布局的设置。 它通过与 systemd-localed.service 通信来修改例如 /etc/locale.conf 与 /etc/vconsole.conf 之类的配置文件。本地化设置控制着 用户界面的语言、字符类型与字符编码、 日

liaowenxiong的博客 5396

字节二面:线程池中线程抛了异常,该如何处理?

???? 欢迎加入小哈的星球,你将获得:专属的项目实战/ Java 学习路线 / 一对一提问 / 学习打卡目前, 正在星球内部带小伙伴做第一个项目:前后端分离博客,手摸手,后端 + 前端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,直到项目上线。目前已更新了105小节,累计14w+字,讲解图:684张,还在持续爆肝中.. 后续还会上新更多项目,愿景是将Java领域典型的项目都整一波...

犬小哈 298

uniapp中renderjs实战:手把手教你实现SSE即时通讯(附完整代码)

本文通过一个完整的实战案例,详细讲解了如何在uni-app中使用RenderJS实现SSE即时通讯功能。文章剖析了RenderJS作为Vue视图层强力补充的原理,并提供了包含自动重连、状态管理等健壮性设计的完整代码,帮助开发者突破框架限制,高效集成浏览器原生API。

weixin_29005499的博客 189

盘点那些好用的SAP FIORI App(二) -上传凭证Upload Journal Entry

SAP FICO运维问题及解决方案分享

lijinbao171022的博客 1542

SpringBoot @Async:魔法和陷阱

来源:https://medium.com/???? 欢迎加入小哈的星球,你将获得:专属的项目实战/ Java 学习路线 / 一对一提问 / 学习打卡/赠书福利目前, 正在星球内部带小伙伴做第一个项目:全栈前后端分离博客,手摸手,后端 + 前端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,直到项目上线。目前已更新了125小节,累计20w+字,讲解图:805张,还在持续爆肝中.. 后...

犬小哈 77

【Godot】构建可维护的游戏工程 —— 项目代码组织结构

本文系统梳理了Godot引擎项目组织原则与架构模式,提出场景中心化、命名规范一致性和资源隔离三大核心原则。推荐按功能模块划分目录结构(如scenes/、entities/、systems/),采用snake_case命名避免跨平台问题,并通过.gdignore优化资源管理。文章详细解析了自包含场景设计、信号驱动解耦等架构技巧,以及团队协作中的版本控制策略,强调通过模块化设计平衡一致性与实用性。最终目标构建清晰可维护的项目结构,使资源定位和功能扩展更加高效。(148字)

qq_40205510的博客 1174

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 284

24、语料库与科技术语库建设

本文探讨了语料库在科技术语库建设中的关键作用,重点分析了词性标注、索引、搭配、词形还原、频率计数、词汇排序和类型-标记分析等核心技术的应用与挑战。文章以印度语言为例,指出其语料库处理工具匮乏的现状,强调需开发适配本地语言特征的技术,并提出一个整合多种处理步骤的综合流程,旨在推动印度语言科技术语数据库的系统化建设,促进科技语言的发展与应用。

cola5的博客 92

硬件工程师提前批真题及答案解析2

我们需要考虑题目可能的简化假设,即输入电阻 Ri​ 可能是 rbe​ 和 βre​ 的组合,但题目可能简化为: Ri​≈rbe​+βre​。由于锗管的正向导通电压较小(0.2 V~0.3 V),而硅管的正向导通电压较大(0.6 V~0.7 V),因此-4.7 V的电压差不符合硅管的特性,而更接近锗管的特性。在三极管电路中,静态电位是指在无信号输入时,三极管各电极的直流电压。re​ 是动态发射极电阻,通常可以近似为 re​=IE​VT​​,但在题目中已经给出了 re​=300Ω,因此可以直接使用这个值。

XU157303764的博客 778

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 346

AgentScope实战训练营:构建计划可视化管理和HITL的AI智能计划助手

本文基于AgentScope Java SDK和Spring Boot WebFlux,从零构建一个支持SSE流式对话、计划可视化管理和HITL的AI智能计划助手Web应用PlanNotebook。涵盖项目架构设计、ReActAgent初始化、自定义工具注册、Hook机制实现、SSE事件协议定义、前端流式渲染等核心技术点,提供完整可运行的代码示例和详细的REST API参考。

program哲学 398

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 126

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Spring Boot 数据源与 MyBatis(-Plus) 自定义配置详解

本文详解 Spring Boot 中单数据源环境下 HikariCP 与 MyBatis-Plus 的自定义配置。通过手动声明 SqlSessionFactory,实现下划线转驼峰、日志输出、一级缓存策略等精细化控制。结合 HikariCP 核心参数调优(如最大连接数、连接生命周期),确保高性能与稳定性。适用于仅需访问单一数据库的场景,避免多数据源复杂性,兼顾性能与可维护性。

BADAO_LIUMANG_QIZHI的博客 196

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

LeetCode Hot 100 二叉树专题(二)3 题(Java)

本篇文章共 3 题:543. 二叉树的直径、102. 二叉树的层序遍历、108. 将有序数组转换为二叉搜索树。 每道题都统一按「① 题目分析 & 解题思路 → ② 常见解法(附代码)及讲解 → ③ 知识点总结」的顺序组织;代码使用 Java 编写,节点定义沿用 LeetCode 默认的 TreeNode。

2401_88612756的博客 365

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【从零理解 Spring AI · 12】MCP 的两种角色:做客户端还是做服务端

上一篇讲了 MCP 的概念:标准协议、三大角色、M+N 替代 M×N。

nice_lcj520的博客 491

JDK 下载安装:装完 Java 提示「不是内部或外部命令」?环境变量没配

JDK 是写 Java 程序必须装的东西。它包含运行 Java 的虚拟机(JRE)和编译 Java 的编译器(javac)——装了它,能跑、.java文件能编译成可执行程序。免费,学习和小规模生产都不花钱。

科小怪的博客 631

java框架大全

java框架大全

qq_39326137的博客 183

Java 多态 学习笔记

多态是面向对象编程的重要特性,指同一操作作用于不同对象时产生不同行为。其核心在于“父类引用指向子类对象”,结合方法重写实现运行时动态绑定。多态使代码更灵活、可扩展,如用Person p = new Student();统一处理各类人员注册,无需修改调用逻辑。但多态无法直接调用子类特有方法,需通过instanceof判断并强制转换。编译时看左边(类型),运行时看右边(实际对象),实现解耦与维护便利。

AA_AA114514的博客 359

SecureRandom做随机源,这个Java随机字符串工具类有3个方法

本文分享一款JDK17环境下的Java随机字符串工具类,内置3个开箱即用的方法,全部采用SecureRandom加密安全随机源,不存在弱随机、可预测、取模偏差等问题。工具类支持默认62字符集随机串、纯数字随机串、自定义字符集随机串三种生成模式,支持Unicode码点级别的字符集处理,兼容Emoji等增补字符,边界处理严格,异常信息明确,适合验证码、邀请码、盐值、随机口令、短链码等场景,源码可直接复制使用。

Java后端 | AI智能体应用实战派 | 电脑技能行家 298

IDEA 简介:从零认识 IntelliJ IDEA

IDEA 全称,是由 JetBrains 公司开发的一款主流 Java 集成开发环境(IDE)。它集代码编辑、编译、调试、测试、版本控制、构建管理等功能于一体,被大量 Java 开发者视为日常开发的首选工具。所谓 IDE(Integrated Development Environment,集成开发环境),就是把写代码所需的各类工具整合到同一个界面中。相比只用文本编辑器加命令行编译,IDE 能显著减少重复操作,让开发者把精力集中在业务逻辑上。

ztI10的博客 136

Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

【代码】Java实现批量线段相交检测(跨积判定+扫描线优化与踩坑复盘)

m0_64476639的博客 328

TRingBuffer两端都能增删(快递站版)

TRingBuffer 是一个支持两端增删、下标访问且容量动态增长的环形双端队列。它通过无符号索引的永不归零设计,利用减法自动模运算实现空满判断与元素计数,避免了传统环形缓冲浪费格子的问题。内部以票号(索引)标记首尾,扩容时重排元素为连续存储,保证 O(1) 操作与高缓存效率。虽不线程安全,但其高效性使其成为游戏开发中事件队列、命令缓冲等场景的理想选择。

u013768914的博客 223

ubuntu安装hadoop系统

本文详细介绍了基于VMware克隆虚拟机搭建三节点Hadoop分布式集群的全过程:使用同一Ubuntu镜像克隆出master、worker1、worker2三台虚拟机,依次配置主机名、固定IP(如192.168.82.10/11/12)、SSH服务及免密登录,确保节点间网络互通。随后安装Java,下载配置Hadoop并分发至各节点,最终初始化启动集群,验证其存储与计算功能,实现高效的大数据环境部署。

qq_43592674的博客 329

Mac上装了最新版本的Android Studio,但是没找到jdk的设置选项也没找到jbr的目录

新版Android Studio(2025.3.1+)因三项变更导致常见问题:一、JDK设置移至“DaemonJVM criteria”,新项目默认自动探测或下载JDK;二、JBR目录改名为带版本号的jbr-21等,需进入.app/Contents/查看,或通过About窗口确认运行时;三、命令行缺adb因platform-tools未加入PATH,需在SDK Manager中勾选并配置~/.zshrc中的ANDROID_HOME及PATH。重装或清理残留可解决缺失问题,切勿手动设JAVA_HOME或安装冲

Programming is a highly artistic endeavor 350
上一篇: Java的线程中断机制
下一篇: 为什么抛出InterruptedException要清除线程中断状态?
程序员7z
博客等级 码龄7年 35粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值