Future 详解

1. Future 是什么?

Future 是 Java 中的一个接口(java.util.concurrent.Future),代表异步计算的未来结果。它允许你:

  • 提交任务后立即返回
  • 在需要时检查任务是否完成
  • 获取任务结果(完成后)
  • 取消任务
2. 怎么使用 Future?

通过线程池提交任务:

ExecutorService executor = Executors.newFixedThreadPool(2);// 提交 Callable 任务(有返回值)
Future<String> future = executor.submit(() -> {TimeUnit.SECONDS.sleep(2);return "任务完成";
});// 其他操作...
String result = future.get(); // 阻塞直到结果就绪
3. Future 的作用
  • 异步解耦:主线程不阻塞等待
  • 结果获取:在需要时通过 get() 取结果
  • 任务控制:支持取消和超时
4. Future 和异步的联系

Future 是 Java 中实现异步编程的核心工具

  • 提交任务即异步执行
  • Future 对象作为"凭证",后续凭此获取结果
  • 典型工作流:
    主线程提交任务
    线程池异步执行
    返回 Future
    继续其他操作
    future.get 取结果
5. 异步 vs 并发
异步并发
非阻塞调用多个任务同时推进
关注单任务的非阻塞性关注多任务管理
Future 是异步工具线程/线程池是并发基础
:网络IO不阻塞主线程:同时处理100个请求
6. Future 和线程的关系
  • 依赖关系:Future 需要线程池执行任务
  • 结果载体:线程池返回 Future 作为结果容器
  • 控制中介:通过 Future 控制任务状态(如取消)
7. 复杂任务处理:Future 组合案例
ExecutorService executor = Executors.newFixedThreadPool(3);// 步骤1:获取用户数据(耗时2秒)
Future<String> userFuture = executor.submit(() -> {TimeUnit.SECONDS.sleep(2);return "用户数据";
});// 步骤2:获取订单数据(依赖用户数据)
Future<String> orderFuture = executor.submit(() -> {String user = userFuture.get(); // 阻塞等待前置任务return user + " + 订单数据";
});// 步骤3:获取推荐数据(独立任务)
Future<String> recommendFuture = executor.submit(() -> {TimeUnit.SECONDS.sleep(1);return "推荐数据";
});// 组合最终结果
String result = orderFuture.get() + " | " + recommendFuture.get();
System.out.println("最终结果: " + result); // 用户数据 + 订单数据 | 推荐数据executor.shutdown();
代码解析:
  1. 线程池管理:使用 3 线程池处理并发
  2. 任务依赖
    • orderFuture 依赖 userFuture.get() 阻塞等待
    • recommendFuture 独立执行
  3. 结果合并
    用户任务
    订单任务
    推荐任务
    结果合并
  4. 总耗时 ≈ 最大路径
    • 路径A→B:2秒
    • 路径C:1秒
    • 最终耗时 ≈ 2秒(非3秒)
执行流程:
timelinetitle 任务时间轴(单位:秒)section 线程1用户任务 : 0 - 2订单任务 : 2 - 2(瞬时完成)section 线程2空闲 : 0 - 1订单等待 : 1 - 2section 线程3推荐任务 : 0 - 1

关键点:Future 适合简单依赖,对于复杂依赖链建议使用 CompletableFuture(支持回调、链式操作)

总结

  • Future 本质:异步任务的结果容器
  • 核心价值:分离任务提交与结果获取
  • 适用场景:IO密集型任务、并行计算、服务组合
  • 进阶建议:Java 8+ 使用 CompletableFuture 增强异步编程能力

线程池深度解析

一、线程池是什么?

线程池(Thread Pool)是一种线程管理机制,它预先创建一组可复用的线程,通过任务队列管理待执行任务。其核心组件包括:

任务队列
线程集合
执行任务
任务提交
线程回收
二、线程池的作用
作用维度具体说明优势对比
资源复用避免频繁创建/销毁线程创建线程成本:约1ms/次 vs 复用成本:≈0
流量控制通过队列缓冲突发请求避免服务器过载崩溃
性能提升减少线程切换开销实测:线程复用比新建快5-10倍
统一管理提供状态监控/任务取消比单个线程更易监控控制
三、线程池 vs 线程的关系
维度线程池独立线程
本质线程资源管理器执行的最小单位
生命周期长期驻留(可复用)执行完立即销毁
关系比喻企业的人力资源部具体干活的员工
创建成本一次性创建多次使用每次任务都新建
使用场景高并发任务(1000+)简单单次任务
四、线程池核心参数

Java中创建线程池的完整参数:

ThreadPoolExecutor(int corePoolSize,    // 常驻核心线程数int maximumPoolSize, // 最大线程数long keepAliveTime,  // 空闲线程存活时间TimeUnit unit,       // 时间单位BlockingQueue<Runnable> workQueue, // 任务队列ThreadFactory threadFactory,       // 线程创建工厂RejectedExecutionHandler handler   // 拒绝策略
)
五、线程池执行流程
提交任务
核心线程
是否空闲?
立即执行
队列是否
未满?
任务入队
能否创建
新线程?
创建临时线程
执行拒绝策略
六、四种拒绝策略对比
策略类型触发条件处理方式适用场景
AbortPolicy队列和线程池全满抛出RejectedException严格要求不丢任务
CallerRunsPolicy同上回退给提交者线程执行核心业务场景
DiscardPolicy同上静默丢弃新任务日志采集等非关键任务
DiscardOldestPolicy同上丢弃队首任务并重试实时性要求高场景
七、线程池使用黄金法则
  1. 严禁使用Executors快捷方法

    • 问题:newFixedThreadPool使用无界队列 → 可能导致OOM
    • 正确:手动创建ThreadPoolExecutor
  2. 合理设置队列容量

    • 计算型任务:队列长度设为 2×核心线程数
    • IO密集型:可设置稍大(但需监控队列堆积)
  3. 监控关键指标

    // 重要监控指标
    executor.getActiveCount();    // 活跃线程数
    executor.getQueue().size();   // 队列积压量
    executor.getCompletedTaskCount(); // 完成数量
    
  4. 线程池关闭姿势

    executor.shutdown(); // 平缓关闭
    if(!executor.awaitTermination(60, SECONDS)) {executor.shutdownNow(); // 强制关闭
    }
    
八、实际应用场景
  1. Web服务器:Tomcat线程池(maxThreads=200 + acceptCount=100
  2. 大数据处理:Spark任务调度池
  3. 金融交易:独立线程池处理不同优先级订单
  4. 微服务架构:Hystrix线程池隔离不同服务调用

通过合理使用线程池,某电商系统性能对比:

指标未用线程池优化后线程池提升
QPS12005600367%
CPU波动20%-95%65%-75%更平稳
响应时间300±250ms50±15ms降83%

CompletableFuture 深度指南

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

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

相关文章

洛谷P1351 [NOIP 2014 提高组] 联合权值

洛谷P1351 [NOIP 2014 提高组] 联合权值 洛谷题目传送门 题目背景 NOIP2014 提高组 D1T2 题目描述 无向连通图 G G G 有 n n n 个点&#xff0c; n − 1 n-1 n−1 条边。点从 1 1 1 到 n n n 依次编号,编号为 i i i 的点的权值为 W i W_i Wi​&#xff0c;每条边的长…

Apache Doris Profile 深度解析:从获取到分析,解锁查询性能优化密码

在 Doris 数据库中&#xff0c;高效的查询性能是数据处理的关键。当我们遇到查询缓慢、资源消耗异常等问题时&#xff0c;Doris 提供的 Profile 工具就如同一位 “性能侦探”&#xff0c;能帮我们抽丝剥茧&#xff0c;找到问题根源。今天&#xff0c;我们就来深入聊聊如何分析 …

系统架构师

硬件&#xff1a; 运算器&#xff1a;1&#xff09;算术运算 加减乘除 2&#xff09;逻辑运算并进行逻辑测试&#xff1a;与或非 组件功能&#xff1a;算术逻辑单元ALU :处理数据 实现对数据的算术运算和逻辑运算 累加寄存器AC 通用寄存器&#xff0c;alu提供工作区 暂存运算结…

Unity HDRP + Azure IoT 工业设备监控系统实例

Unity HDRP Azure IoT 工业设备监控系统实例 下面是一个完整的工业设备监控解决方案&#xff0c;结合Unity HDRP&#xff08;高清渲染管线&#xff09;的高质量可视化与Azure IoT的实时数据处理能力。 系统架构 #mermaid-svg-XJnD6acrBbtbqYHW {font-family:"trebuchet…

(超详细)数据库项目初体验:使用C语言连接数据库完成短地址服务(本地运行版)

数据库项目初体验&#xff1a;使用C语言连接数据库完成短地址服务&#xff08;本地运行版&#xff09; 前言&#xff1a;初学者的思考 作为一个刚初学数据库的小白并且在之前我的博客中我有尝试使用C语言写过一个短地址服务&#xff0c;但是使用C语言编写的短地址服务只有短记…

mysql基础(一)快速上手篇

连接mysql 使用命令行窗口连接mysql数据库 语法&#xff1a;mysql –h主机名 –u用户名 –p密码 说明&#xff1a;-h参数指定数据库ip&#xff0c;本地服务器可以用localhost&#xff0c;-u参数指定用户名&#xff0c;-p参数指定用户密码。 注意&#xff1a;-p和密码值之间…

IntelliJ IDEA 2025- 下载安装教程图文版详细教程(附激活码)

目录 写在前面 一、介绍 二、下载 三、安装 &#x1f3c1; 写在最后 写在前面 > &#x1f680; 初学 Java&#xff1f;或者刚开始写项目&#xff0c;不知道该选哪个 IDE&#xff1f; 本篇教程手把手教你安装 IntelliJ IDEA —— JetBrains 出品的顶级 Java 开发环境&a…

数学经济专业大学四年规划

数学经济专业结合了数学的逻辑严谨性和经济学的现实应用性&#xff0c;为学生提供了强大的数理分析能力和经济洞察力。该专业毕业生在金融科技、量化投资、商业分析等领域具有显著优势&#xff0c;尤其在数字经济时代&#xff0c;这类复合型人才的需求量持续增长。一、数学经济…

局域网打印机共享怎么设置?如何配置内网本地网络打印机给异地电脑远程连接使用打印?

打印机共享怎么设置&#xff1f;如何设置本地内网的网络打印机共享给其他网络下电脑连接打印&#xff1f;打印机设置使用以及异地使用打印都是大家比较关注的问题&#xff0c;下面详细教程中分二步&#xff0c;先讲局域网内的打印机共享&#xff0c;再进一步介绍内网打印机地址…

Rust异步爬虫实现与优化

Rust 语言在爬虫领域的应用相对较少&#xff0c;尽管 Rust 的 async/await 已稳定&#xff0c;但其与线程安全、Pin 等概念的结合仍较复杂&#xff0c;而爬虫高度依赖并发处理&#xff0c;进一步提高了开发成本。这就导致了使用Rust语言爬虫用的人很少。 下面是一个使用 Rust 编…

Electron 安全最佳实践:构建安全的桌面应用

Electron 是一个流行的框架&#xff0c;允许开发者使用 Web 技术&#xff08;HTML、CSS、JavaScript&#xff09;构建跨平台桌面应用。许多知名应用&#xff0c;如 VS Code、Slack 和 Discord&#xff0c;都基于 Electron 开发。然而&#xff0c;由于其结合了 Node.js&#xff…

MySQL 事务详解:从基础操作到隔离级别与 MVCC 原理

前言 首先从概念上进行理解什么是事务&#xff0c;以及事务的4大属性&#xff0c;知道是什么还要知道为什么&#xff1f; 事务是如何进行操作的&#xff0c;最后在谈事务的隔离性、隔离级别&#xff08;最重要但是也很难理解&#xff09;&#xff0c;理解隔离级别体现在哪里 …

【Unity 编辑器工具开发:GUILayout 与 EditorGUILayout 对比分析】

Unity 编辑器工具开发&#xff1a;GUILayout 与 EditorGUILayout 对比分析 一、核心区别对比 方面GUILayoutEditorGUILayout区别命名空间UnityEngineUnityEditorEditorGUILayout 仅限编辑器环境适用范围游戏运行时 编辑器工具仅限编辑器工具运行时禁用 EditorGUILayout渲染管…

[附源码+数据库+毕业论文]基于Spring+MyBatis+MySQL+Maven+jsp实现的个人财务管理系统,推荐!

摘 要 随着软件信息技术的兴起&#xff0c;许多手工作业也升级为软件管理数据&#xff0c;本次针对个人财务数据的管理&#xff0c;开发一款个人财务管理系统&#xff0c;该系统可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及…

Compose入门3 - 高仿小红书 界面

使用compose 实现一个小红书UI 界面&#xff0c;主要是为了锻炼 使用compose布局的能力 demo地址&#xff1a;https://github.com/PangHaHa12138/ComposeDemo 先上demo 截图 下面是完整的compose代码 package com.example.test001import android.annotation.SuppressLint imp…

mybatis-plus json字段使用typeHandler自动转换为List

mybatis-plus json字段使用typeHandler自动转换为List mybatis-plus json字段使用typeHandler自动转换为List 一、实现思路 1.配置mybatis配置&#xff0c;注入handlermybatis-plus:typeHandlersPackage: com.power.common.core.handler 2.字段顶部增加注解TableField(typeHand…

(C++)学生管理系统(测试2版)(map数组的应用)(string应用)(引用)(C++教学)(C++项目)

1. 头文件与命名空间 #include <iostream> // 输入输出流库&#xff0c;提供cin/cout等基本I/O功能 #include <map> // 映射容器库&#xff0c;提供map数据结构&#xff08;键值对集合&#xff09; #include <string> // 字符串库&#xff0c;…

使用assembly解决jar包超大,实现依赖包、前端资源外置部署

成果物需要部署到用户内网的童鞋应该都遇到过该问题&#xff1a;引入的maven依赖越来越多&#xff0c;jar包越来越大&#xff0c;我之间甚至见过一两个G的依赖&#xff0c;想改个代码换到现场测试&#xff0c;包传到现场要一二十分钟&#xff0c;真正实现了改代码两分钟分钟&am…

基于PHP+MySQL实现(Web)英语学习与测试平台

数据库课设&#xff1a;英语学习与测试平台 运行环境要求 PHP7.1 基于 thinkPHP6.0、Layui、Xadmin 开发 主要功能 公共模块 登录注册个人信息修改密码修改 教师模块 文章查看发布班级管理测试查看发布批改历史成绩查看 学生模块 文章查看参与测试查看成绩 管理员模块…

WinForm中Settings.settings和app.config修改后信息不同步到exe.config问题

在 WinForms 项目中&#xff0c;Settings.settings 和 app.config/exe.config 的关系确实容易让人困惑。以下是问题的根本原因和解决方案&#xff1a; 问题本质 设计时文件&#xff1a;app.config&#xff08;源码中的配置文件&#xff09;运行时文件&#xff1a;bin/Debug/Yo…