广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java多线程 Callable、Future 和FutureTask
  • 378
分享到

Java多线程 Callable、Future 和FutureTask

2024-04-02 19:04:59 378人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录1 Callable介绍2 Future介绍2.1 在Future接口中声明方法2.2 Future提供了三种功能3 FutureTask4 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<V> implements RunnableFuture<V>

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


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

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

FutureTask提供了2个构造器:


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

事实上,FutureTaskFuture接口的一个唯一实现类。

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<Integer> 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<Integer> {

    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<Integer> future =es.submit(calTask);
//      //关闭线程池
//      es.shutdown();

        //创建线程池
        ExecutorService es = Executors.newSingleThreadExecutor();
        //创建Callable对象任务
        CallableDemo calTask = new CallableDemo();
        //创建FutureTask
        FutureTask<Integer> 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<Integer> {

    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类中
   
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);//可以看到源码中其实是在submit(Callable<T> task)内部创建了一个RunnableFuture<T>接口实现类
        execute(ftask);
        return ftask;
    }

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


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

到此这篇关于Java多线程 CallableFuture FutureTask的文章就介绍到这了,更多相关Java多线程内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java多线程 Callable、Future 和FutureTask

本文链接: https://www.lsjlt.com/news/155682.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java多线程 Callable、Future 和FutureTask
    目录1 Callable介绍2 Future介绍2.1 在Future接口中声明方法2.2 Future提供了三种功能3 FutureTask4 Future和FutureTask的...
    99+
    2022-11-12
  • Java多线程中Callable、Future和FutureTask是什么意思
    小编给大家分享一下Java多线程中Callable、Future和FutureTask是什么意思,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言:创建线程的2种...
    99+
    2023-06-25
  • java多线程编程同步器Future和FutureTask解析及代码示例
    publicinterfaceFuture<V>Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用get方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消...
    99+
    2023-05-30
    java 多线程 ava
  • Java中Future和FutureTask怎么用
    小编给大家分享一下Java中Future和FutureTask怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、Future 接口当 call()方法完成时,结果必须存储在主线程已知的对象中,以便主线程可以知道该线程...
    99+
    2023-06-21
  • Java并发教程之Callable和Future接口详解
    刚把Thread 的知识理了一遍。 Runnable是一个接口,而Thread是Runnable的一个实现类。 所以也就有了之前创建线程的两种方法 继承Thread ...
    99+
    2022-11-12
  • 详解JDK中ExecutorService与Callable和Future对线程的支持
    详解JDK中ExecutorService与Callable和Future对线程的支持代码背景:    假如有Thread1、Thread2、Thread3、Thread4四条线程分别统计C、D、E、F四个盘的...
    99+
    2023-05-31
    jdk executorservice ce
  • Java中Future和FutureTask的示例详解及使用
    目录一、Future 接口二、FutureTask三、使用 Callable 和 Future四、小结(FutureTask核心原理)总结一、Future 接口 当 call()方法...
    99+
    2022-11-12
  • Java多线程并发FutureTask使用详解
    目录基本使用代码分析继承关系FutureRunnableFutureFutureTask状态属性内部类构造方法检索 FutureTask 状态取消操作计算结果立刻获取结果或异常run...
    99+
    2022-11-13
  • Java中如何使用Callable和Future接口详解
    本篇文章给大家分享的是有关Java中如何使用Callable和Future接口详解,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Runnable是一个接口,而Thread是Ru...
    99+
    2023-06-20
  • Java多线程之Future设计模式
    目录Future -> 代表的是未来的一个凭据AsynFuture -> Future具体实现类FutureService -> 桥接Future和FutureTa...
    99+
    2022-11-12
  • Java多线程之FutureTask的介绍及使用
    目录一、FutureTask的理解二、FutureTask类图三、FutureTask类中常用方法四、FutureTask类的使用示例一、FutureTask的理解 FutureTa...
    99+
    2022-11-12
  • 在Java中如何使用Callable、Future进行并行编程
    这篇文章将为大家详细讲解有关在Java中如何使用Callable、Future进行并行编程,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。使用Callable、Future进行并行编程在Java中进行并行编...
    99+
    2023-05-30
    java callable future
  • 如何在Java中使用FutureTask实现多线程
    如何在Java中使用FutureTask实现多线程?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、FutureTask的理解FutureTask属于java.util.con...
    99+
    2023-06-15
  • Java多线程Callable接口实现代码示例
    对于多线程,大家并不陌生,对于如何创建线程也是轻车熟路,对于使用new thread和实现runable接口的方式,不再多说。这篇博文我们介绍第三种:实现Callable接口。Callable接口接口定义:@FunctionalInterf...
    99+
    2023-05-30
    java 多线程 接口
  • Java使用Runnable和Callable实现多线程的区别详解
    使用Runnable和Callable接口实现多线程的区别 先看两种实现方式的步骤: 1.实现Runnable接口 public class ThreadDemo{ publ...
    99+
    2022-11-13
  • Java的Future多线程模式怎么使用
    本篇内容介绍了“Java的Future多线程模式怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在Java5后,提供了大量处理多线程的...
    99+
    2023-06-17
  • Java使用Runnable和Callable实现多线程的区别是什么
    这篇文章主要介绍“Java使用Runnable和Callable实现多线程的区别是什么”,在日常操作中,相信很多人在Java使用Runnable和Callable实现多线程的区别是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作...
    99+
    2023-07-02
  • Java多线程中Future设计模式怎么用
    这篇文章将为大家详细讲解有关Java多线程中Future设计模式怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Future -> 代表的是未来的一个凭据public interfac...
    99+
    2023-06-25
  • 多线程Thread,Runnable,Callable实现方式
    目录一、创建线程的常用三种方式1、继承Thread类2、实现Runnable接口(重点)以多个线程并发,解决方法为例3、 实现Callable接口(JDK1.5版本之后引入的)总结一...
    99+
    2022-11-12
  • 怎么使用Java多线程Future获取异步任务
    本篇内容主要讲解“怎么使用Java多线程Future获取异步任务”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用Java多线程Future获取异步任务”吧!Runnable的局限性在前文中...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作