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

java之Future

一、Future是什么

  • future是"异步计算的凭证",启动线程池异步计算后,如果想拿到结果该怎么获取?使用异步线程池返回的Future
  • 线程池的submit方法的返回值类型就是Future
    在这里插入图片描述 - 怎么获取返回的结果?调用Future的get()/get(long timeout, TimeUnit unit)
@Testpublic void testSXFCache() throws ExecutionException, InterruptedException {// 创建一个线程池ExecutorService executorService = Executors.newFixedThreadPool(10);// 使用submit方法提交任务,得到Future对象Future<Integer> future = executorService.submit(() -> {try {Thread.sleep(2000);return 20;} catch (InterruptedException e) {throw new RuntimeException(e);}});Integer integer = future.get();// 使用future对象得到结果executorService.shutdown();log.info("结果为:{}", integer);}

二、Future的作用

不同的Future实现类有不同的额外作用,Future类是最顶层的抽象类,它的核心价值是:

  • 提交任务后,立刻拿到"提货单":线程池/异步框架执行耗时任务时,不会阻塞调用线程,而是返回一个"提货单"Future,可以让调用线程执行完其他操作后,再获取异步任务的结果
  • 提供 结果、控制、状态三大能力:
结果get() / get(timeout) 获取计算结果(可阻塞可超时)
状态isDone() / isCancelled() 查询任务是否完成/被取消
控制cancel(mayInterruptIfRunning) 尝试取消任务

三、Future的常用API

方法说明
V get()阻塞直到任务完成并返回结果
V get(long timeout, TimeUnit unit)带超时的阻塞
boolean cancel(boolean mayInterruptIfRunning)尝试取消任务
boolean isCancelled()任务是否已取消
boolean isDone()任务是否已结束(含正常/异常/取消)

四、底层AQS

这个后面还要继续深入学习

五、Future的回调/注册监听器

1、JDK原生Future

  • 没有回调机制,只能阻塞get;

2、CompletableFuture

  • 链式回调:thenApply、thenApplyAsync等等这些方法都会返回新的 CompletableFuture,可无限链。
  • 这个后面还需要再学习

3、ListenableFuture

  • 使用addListener 方法回调
  • addListener方法可以通过异步线程池创建新的线程执行回调方法
  • 核心方法:
方法是否异步默认线程池示例
addListener(Runnable, Executor)由 Executor 决定必须传同步用 directExecutor(),异步传线程池
Futures.addCallback(f, callback, executor)同上必须传等价写法,更友好
  • 触发条件:Future 被标记为“已完成”(isDone() 瞬间变成 true),无论结果是成功、失败、取消或异常,只要状态变成已完成,就会触发回调。

六、Future与线程池的关系

  • Future是获取结果的类,是"提货凭证";
  • 线程池是实现异步的方式,线程池可以实现异步的效果;线程池可以开启新的线程执行,不阻断调用线程

七、几种Future实现类

CompletableFuture (JDK 8+ 自带)

  • 不需要通过创建异步线程池的得到CompletableFuture,调用CompletableFuture的supplyAsync无参方法时,它会把任务提交到默认的ForkJoinPool.commonPool()(一个JVM全局共享、大小 = CPU 核心数-1的线程池,无需手动创建 )
  • 也可以显示指定线程池
// 1. 无显式线程池 → 用 commonPool
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> heavyTask());// 2. 显式指定线程池 → 走自己的池
ExecutorService myPool = Executors.newCachedThreadPool();
CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> heavyTask(), myPool);

ListenableFuture

  • Google Guava 提供
  • Futures.immediateFuture方法:

| 零延迟 | 返回瞬间 isDone() = trueget() 立刻拿到原值;无后台线程。 |
| 零阻塞 | 调用 get() 不会睡线程;主线程继续跑。 |
| 零异常 | 除非你把 null 当异常,否则永不抛 ExecutionException。 |
| 零资源 | 内部只是一个 ImmediateFuture 单例,不创建 Thread不占用线程池。 |

特点说明
零延迟调用该方法后立刻拿到原值,无后台线程;立即返回isDone() = true
零阻塞这个方法是同步方法,同步返回,但调用get方法不会阻塞主线程,主线程继续跑
零资源不创建Thread、不占用线程池
  • 个人理解这个方法的目的:返回一个future类型对象,传入一个value,不需要异步线程执行任何操作,调用get方法时,返回传入的value,仅此而已;目的是保持代码统一,调用方法时都能使用Future对象接收,都可以调用get方法、isDone方法。

SettableFuture

  • Google Guava 提供
  • SettableFuture类似空白支票,
  • “可手动完成”**的 ListenableFuture 实现类,
  • 创建时不带任何结果;
  • 所有阻塞在 get() 上的线程会被立刻唤醒且拿到结果;
  • 可以在任意时刻调用 set(V) 或 setException(Throwable) 把它标记为成功或失败
方法作用
static <V> SettableFuture<V> create()新建一个未完成的实例
boolean set(V value)手动填成功结果;返回 true(false 表示已被 set)
boolean setException(Throwable t)手动填异常;返回 true
boolean cancel(boolean mayInterruptIfRunning)同父接口,也可直接取消
  • 使用示例:
SettableFuture<Data> future = SettableFuture.create();// 消费者线程等待
new Thread(() -> {try {Data data = future.get(); // 阻塞直到 setprocess(data);} catch (ExecutionException e) {handleError(e.getCause());}
}).start();// 生产者线程计算完成后 set
new Thread(() -> {Data data = longTimeCompute();future.set(data);           // 立即唤醒消费者
}).start();

八、CompletableFuture和ListenableFuture比较

维度CompletableFuture (JDK 8+)ListenableFuture (Guava)
所属库官方 JDK (java.util.concurrent)Google Guava
核心能力Future + 链式阶段 (CompletionStage)Future + 监听器
链式操作内置 thenApply/thenCompose/handle/exceptionallyFutures.transform/addListener
异常处理链内传播 handle/exceptionally手动 Futures.catching
多任务合并allOf/anyOf/thenCombineFutures.allAsList/successfulAsList
异步执行默认 ForkJoinPool(可自定义)必须传 Executor
非阻塞回调原生支持需指定 Executor
取消/超时orTimeout/completeOnTimeout(JDK 9+)需 ScheduledExecutor
兼容旧 JDK≥ JDK 8≥ JDK 7
依赖体积0(官方)+ Guava jar
学习成本(官方文档+社区大)(Guava API 文档)

一句话选型

JDK 8+ 新项目 → CompletableFuture(功能全、零依赖、社区大);
老系统/已深度用 Guava → ListenableFuture(无缝衔接,但链式能力稍弱)。

以上来自GPT,Future可学习的还有很多,比如链式操作、多任务合并等。

九、MoreExecutors.directExecutor()

  • 在学习的过程中见到了MoreExecutors.directExecutor();
  • Guava 提供的 “当前线程执行器”;
  • 作用:不切换线程,任务在哪条线程提交,就在哪条线程立即运行——零延迟、零线程切换、零上下文开销。
  • 代码实现:直接返回当前Executor
    在这里插入图片描述
  • 使用场景:
  • 轻量级回调:只打印日志等
http://www.dtcms.com/a/544944.html

相关文章:

  • Projection Error: Explanation and Causes 关于投影误差的解释与说明
  • php网站开发模板织梦移动端网站模板下载地址
  • 【JavaEE初阶】TCP的核心机制6——拥塞控制
  • LangChain4j学习一:聊天和语言模型
  • LeetCode hot100:056 合并区间:高效算法解析
  • uni-app开发入门手册
  • 做网站属于程序员吗网站搭建php源码
  • 什么是支架电容,它的原理是什么
  • 仓颉UI开发精髓:构建高复用、可组合的自定义组件
  • 校园文化宣传主题网站的建设做门户网站多少钱
  • 深入理解 Rust 的 Iterator Trait:惰性与抽象的力量
  • vs做网站怎么加文件夹商丘销售网站制作
  • 自定义ViewGroup实现要点
  • docker学习笔记,从入门开始!
  • 从 MVC 5 到 Core MVC:ASP.NET MVC 框架的 “进化之路“
  • 认识人工智能与大模型应用开发
  • 电子学会青少年机器人技术(一级)等级考试试卷-实操题(2025年9月)
  • 亲 怎么给一个网站做备份哪些专业能建网站
  • JWT 全面解析与 Spring Boot 实战教程
  • 【预览PDF】前端预览pdf
  • 【PrintPDF】PrintPDF Cargo.toml 分析
  • R/3 销售与分销
  • 唐山微网站建设价格网站建设信息发布
  • 做的最好的理财网站国内无版权图片网站
  • GXDE OS 支持在 WSL 上使用了(带桌面环境)
  • 【Linux】基础指令(2):理解Linux的指令和核心概念
  • Rust 借用分割技巧:安全解构复杂数据结构
  • 在Vue项目中平滑地引入HTML文件
  • 1688网站特点石家庄模板网站建设
  • 不练不熟,不写就忘 之 compose 之 动画之 animateDpAsState动画练习