一文搞懂Java异步编程之FutureTask(转)
背景
Java异步编程的在实际开发中经常被用到,那么异步任务执行结束如何将结果通知到主线程或者其他任务呢?本文不探讨JUC包下的各类锁实现实现的任务同步或者通知。
一、Thread
狭隘的讲Java创建线程的方式只有一种,就是new Thread实例。Thread本身是Runnable的实现并且它定义了Runnable的field,所以支持自定义实现Runnable接口后,在new实例时构造Thread,最终一个新建的线程都需要通过调用start()执行。
这里有一点值得拿出来讲讲,如果直接执行Thread的run(),那么这时候并不是多线程的,它其实就是在主线程中执行了Runnable中定义的普通run方法。
由于Thread没有返回值,异步处理完的结果获取就有点麻烦。到了JDK1.5的时候,Callable和Future被引入,返回线程执行结果。
二、Future与FutureTask
讲到这里终于点题了,Future是一个接口,可以对Runnable或者Callable的task进行取消、判断是否取消、判断是否完成、获取执行结果;执行结果的获取是阻塞,直到task返回结果或者超时当前线程才会继续往下执行。
Future是一个接口,FutureTask是它的实现类,它的继承关系如下,
public class FutureTask<V> implements RunnableFuture<V> public interface RunnableFuture<V> extends Runnable, Future<V>
因此它可以作为Runnable被线程执行
public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<String> futureTask = new FutureTask<>(() -> { System.out.println(Thread.currentThread().getName()); // Thread-0 System.out.println("Runnable implements"); // Runnable implements }, null); new Thread(futureTask).start(); System.out.println(Thread.currentThread().getName()); // main String result = futureTask.get(); System.out.println(result); // null }
上示例代码,输出内容顺序为 main-》Thread-0-》Runnable implements-》null 。最终输出null是因为FutureTask的构造函数中传入的就是null,如果有需要可以传值给异步任务处理,通过自定义Task类实现Runnable接口,把传值作为field给到Task处理。
小结
Future可以很容易的获得异步执行的结果,并且对任务进行一些操控;get等待结果时会阻塞,所以当任务之间有依赖关系的时候,一个任务依赖另一个任务的结果,可以用Future的get来等待依赖的任务完成的结果。
FutureTask是实现类,有Runnable的特性又有Future的特性,内部包的是Callable ,当然也有接受Runnable的构造器,只是会偷偷把Runnable转成Callable来实现能返回结果的方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现