千家信息网

Java多线程中Callable、Future和FutureTask是什么意思

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,小编给大家分享一下Java多线程中Callable、Future和FutureTask是什么意思,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我
千家信息网最后更新 2026年11月03日Java多线程中Callable、Future和FutureTask是什么意思

小编给大家分享一下Java多线程中Callable、Future和FutureTask是什么意思,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

前言:

创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。
这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。
如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。
而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果

1 Callable介绍

Callable接口代表一段可以调用并返回结果的代码;Future接口表示异步任务,是还没有完成的任务给出的未来结果。所以说Callable用于产生结果,Future用于获取结果。

Callable接口使用泛型去定义它的返回类型。Executors类提供了一些有用的方法在线程池中执行Callable内的任务。由于Callable任务是并行的(并行就是整体看上去是并行的,其实在某个时间点只有一个线程在执行),我们必须等待它返回的结果。
java.util.concurrent.Future对象为我们解决了这个问题。在线程池提交Callable任务后返回了一个Future对象,使用它可以知道Callable任务的状态和得到Callable返回的执行结果。Future提供了get()方法让我们可以等待Callable结束并获取它的执行结果。

2 Future介绍

2.1 在Future接口中声明方法

在Future接口中声明5种方法下面依次解释每个方法的作用:

2.2 Future提供了三种功能

  • 1)判断任务是否完成;

  • 2)能够中断任务;

  • 3)能够获取任务执行结果。

因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。

3 FutureTask

我们先来看一下FutureTask的实现:

public class FutureTask implements RunnableFuture

FutureTask类实现了RunnableFuture接口,我们看一下RunnableFuture接口的实现:

public interface RunnableFuture extends Runnable, Future {    void run();}

可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。

FutureTask提供了2个构造器:

public FutureTask(Callable callable) {}public FutureTask(Runnable runnable, V result) {}

事实上,FutureTask是Future接口的一个唯一实现类。

4 Future和FutureTask的使用

4.1 使用Callable+Future获取执行结果

public class CallableFutureTest {    public static void main(String[] args) {        //创建线程池        ExecutorService es = Executors.newSingleThreadExecutor();        //创建Callable对象任务        CallableDemo calTask = new CallableDemo();        //提交任务并获取执行结果        Future future = es.submit(calTask);        //关闭线程池        es.shutdown();        try {            Thread.sleep(2000);            System.out.println("主线程在执行其他任务");            if (future.get() != null) {                //输出获取到的结果                System.out.println("future.get()-->" + future.get());            } else {                //输出获取到的结果                System.out.println("future.get()未获取到结果");            }        } catch (Exception e) {            e.printStackTrace();        }        System.out.println("主线程在执行完成");    }}class CallableDemo implements Callable {    private int sum;    @Override    public Integer call() throws Exception {        System.out.println("Callable子线程开始计算啦!");        Thread.sleep(2000);        for (int i = 0; i < 100; i++) {            sum = sum + i;        }        System.out.println("Callable子线程计算结束!");        return sum;    }}

Callable子线程开始计算啦!
Callable子线程计算结束!
主线程在执行其他任务
future.get()-->4950
主线程在执行完成

4.2 使用Callable+Future获取执行结果

public class CallableFutureTest {    public static void main(String[] args) {//      //创建线程池//      ExecutorService es = Executors.newSingleThreadExecutor();//      //创建Callable对象任务//      CallableDemo calTask=new CallableDemo();//      //提交任务并获取执行结果//      Future future =es.submit(calTask);//      //关闭线程池//      es.shutdown();        //创建线程池        ExecutorService es = Executors.newSingleThreadExecutor();        //创建Callable对象任务        CallableDemo calTask = new CallableDemo();        //创建FutureTask        FutureTask futureTask = new FutureTask<>(calTask);        //执行任务        es.submit(futureTask);        //关闭线程池        es.shutdown();        try {            Thread.sleep(2000);            System.out.println("主线程在执行其他任务");            if (futureTask.get() != null) {                //输出获取到的结果                System.out.println("futureTask.get()-->" + futureTask.get());            } else {                //输出获取到的结果                System.out.println("futureTask.get()未获取到结果");            }        } catch (Exception e) {            e.printStackTrace();        }        System.out.println("主线程在执行完成");    }}class CallableDemo implements Callable {    private int sum;    @Override    public Integer call() throws Exception {        System.out.println("Callable子线程开始计算啦!");        Thread.sleep(2000);        for (int i = 0; i < 100; i++) {            sum = sum + i;        }        System.out.println("Callable子线程计算结束!");        return sum;    }}

Callable子线程开始计算啦!
Callable子线程计算结束!
主线程在执行其他任务
futureTask.get()-->4950
主线程在执行完成

但其实这两种方法最终是一样的:
第一种方式Callable+Future最终也是以Callable+FutureTask的形式实现的。
在第一种方式中调用了: Future future = executor.submit(task);
那就让我们看看executor.submit(task)的源码吧:

//java.util.concurrent.AbstractExecutorService类中   /**     * @throws RejectedExecutionException {@inheritDoc}     * @throws NullPointerException       {@inheritDoc}     */    public  Future submit(Callable task) {        if (task == null) throw new NullPointerException();        RunnableFuture ftask = newTaskFor(task);//可以看到源码中其实是在submit(Callable task)内部创建了一个RunnableFuture接口实现类        execute(ftask);        return ftask;    }

而FutureTask又是RunnableFuture的实现类,那就再看看newTaskFor(Callable callable)里面干了什么:

 protected  RunnableFuture newTaskFor(Callable callable) {        return new FutureTask(callable);    }

以上是"Java多线程中Callable、Future和FutureTask是什么意思"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

线程 任务 结果 接口 对象 方法 方式 输出 就是 篇文章 意思 内容 源码 不怎么 事实 事实上 代码 代表 作用 前言 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 手磨咖啡 科技互联网 互联网科技活动banner 厦门中拓互联网络科技有限公司 互联网科技公司官网 互联网科技小额贷款 衡水科技产业互联网平台 现代科技和互联网有关系吗 深圳前海聚择互联网科技有限公司 福州新华互联网科技学校 知乎 民营互联网公司国防科技 朱啸虎曾投资哪些互联网科技企业 山东有哪些互联网科技公司 雨阳互联网卡科技有限公司 东营紫格互联网科技 易企秀互联网科技是做什么的 互联网科技职业技能培训学校 互联网科技对化妆品行业 科技互联网专业工作会议发言稿 山东亿川互联网科技有限责任公司 高科技互联网 美国互联网保险保险科技 智能科技公司是互联网公司吗 科技制造互联网公司 互联网金融科技创新 致聘互联网科技 成都狮子座互联网科技 无锡溥仪互联网科技有限公司 互联网5g黑科技有哪些 玉溪新华互联网科技好不好
0