Java多线程之FutureTask的介绍及使用

 更新时间:2021年06月04日 17:11:26   作者:小志的博客  
之前介绍了线程池相关的对象,Runable Callable与Future,下面介绍FutureTask的作用,它的特性是怎样的呢,需要的朋友可以参考下

一、FutureTask的理解

FutureTask属于java.util.concurrent 包;FutureTask表示可取消的异步计算。FutureTask类提供了一个Future的基本实现 ,具有启动和取消计算的方法,查询计算是否完整,并检索计算结果。结果只能在计算完成后才能检索; 如果计算尚未完成,则get方法将阻止。 一旦计算完成,则无法重新启动或取消计算(除非使用runAndReset()调用计算 )。

二、FutureTask类图

在这里插入图片描述

从上面的FutureTask类图中可以看出,FutureTask实现了RunnableFuture接口,RunnableFuture接口继承了Runnable接口和Future接口,所以FutureTask兼备Runnable和Future两种特性

在这里插入图片描述
在这里插入图片描述

三、FutureTask类中常用方法

在这里插入图片描述

1、构造方法

  • public FutureTask(Callable callable) 创建一个 FutureTask ,它将在运行时执行给定的 Callable 。 参数: callable表示可调用任务 。
  • public FutureTask(Runnable runnable,V result) 创建一个 FutureTask ,将在运行时执行给定的 Runnable ,并安排 get将在成功完成后返回给定的结果。 参数:runnable 表示可运行的任务 ;result 表示成功完成后返回的结果。

2、常用的方法

  • public boolean isCancelled() 如果此任务在正常完成之前取消,则返回 true 。
  • public boolean isDone() 返回true如果任务已完成。
  • public V get() 等待计算完成,然后检索其结果。
  • public V get(long timeout, TimeUnit unit)如果需要等待最多在给定的时间计算完成,然后检索其结果(如果可用)。
  • public boolean cancel(boolean mayInterruptIfRunning)尝试取消执行此任务。
  • protected void set(V v)将此未来的结果设置为给定值,除非此未来已被设置或已被取消。

四、FutureTask类的使用示例

示例参考此博文:Java FutureTask类使用

案例场景
通过示例进行多任务计算,通过get()方法可以异步获取执行结果。

1、创建一个计算任务类,实现Callable接口,重写call方法

package com.xz.thread.FutureTask;

import java.util.concurrent.Callable;

/**
 * @description: 创建一个计算任务类,实现Callable接口,重写call方法
 * @author: xz
 * @create: 2021-06-02 22:06
 */
public class ComputeTask implements Callable<Integer> {

    private String taskName;//任务名称

    //任务构造器
    public ComputeTask(String taskName) {
        this.taskName = taskName;
        System.out.println("创建【计算任务】开始,计算任务名称:" + taskName);
    }

    //计算任务的方法
    @Override
    public Integer call() throws Exception {
        Integer result = 0;
        for (int i = 1; i <=50; i++) {
            result = +i;
        }
        System.out.println("【计算任务】"+taskName +"执行完成。");
        return result;
    }
}

2、创建一个测试类

package com.xz.thread.FutureTask;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

/**
 * @description:
 * @author: xz
 * @create: 2021-06-01 22:44
 */
public class Demo {
    public static void main(String[] args) {
        //任务集合
        List<FutureTask<Integer>> futureTasks  = new ArrayList<>();
        //创建固定长度的线程池
        ExecutorService pool = Executors.newFixedThreadPool(5);
        for (int i = 1; i <= 10; i++) {
            //实例化FutureTask,传入计算任务类
            FutureTask<Integer> futureTask = new FutureTask<>(new ComputeTask(i + ""));
            //添加到任务集合中
            futureTasks.add(futureTask);
            //提交任务到线程池
            pool.submit(futureTask);
        }
        System.out.println("所有【计算任务】提交完毕,主线程开始执行");

        System.out.println("【主线程任务】开始============");
        //主线程睡眠5秒,模拟主线程做某些任务
        try {
            Thread.sleep(5000);
            System.out.println("【主线程任务】开始执行某些任务============");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("【主线程任务】结束============");

        //用于打印任务执行结果
        Integer result = 0;
        for (FutureTask<Integer> task : futureTasks) {
            try {
                //FutureTask的get()方法会自动阻塞,知道得到任务执行结果为止
                result += task.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        //关闭线程池
        pool.shutdown();
        System.out.println("多线程多任务执行结果:" + result);

    }

}

3、输出结果如下:

创建【计算任务】开始,计算任务名称:1
创建【计算任务】开始,计算任务名称:2
创建【计算任务】开始,计算任务名称:3
创建【计算任务】开始,计算任务名称:4
创建【计算任务】开始,计算任务名称:5
创建【计算任务】开始,计算任务名称:6
创建【计算任务】开始,计算任务名称:7
创建【计算任务】开始,计算任务名称:8
创建【计算任务】开始,计算任务名称:9
创建【计算任务】开始,计算任务名称:10
所有【计算任务】提交完毕,主线程开始执行
【主线程任务】开始============
【计算任务】1执行完成。
【计算任务】2执行完成。
【计算任务】6执行完成。
【计算任务】7执行完成。
【计算任务】9执行完成。
【计算任务】10执行完成。
【计算任务】8执行完成。
【计算任务】4执行完成。
【计算任务】3执行完成。
【计算任务】5执行完成。
【主线程任务】开始执行某些任务============
【主线程任务】结束============
多线程多任务执行结果:500

在这里插入图片描述

4、结论

通过FutureTask类的get()方法可用于异步获取执行结果,无论FutureTask调用多少次run()或者call()方法,它都能确保只执行一次Runable或Callable任务。

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

相关文章

  • springboot实现简单的消息对话的示例代码

    springboot实现简单的消息对话的示例代码

    本文主要介绍了springboot实现简单的消息对话的示例代码,可以使用WebSocket技术,WebSocket是一种在客户端和服务器之间提供实时双向通信的协议,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • java、freemarker保留两位小数

    java、freemarker保留两位小数

    这篇文章主要介绍了 java、freemarker保留两位小数的实现方法,然后给大家补充介绍了freemarker保留两位小数的详解,需要的朋友可以参考下
    2017-03-03
  • Netty分布式pipeline管道Handler的添加代码跟踪解析

    Netty分布式pipeline管道Handler的添加代码跟踪解析

    这篇文章主要介绍了Netty分布式pipeline管道Handler的添加代码跟踪解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • java实现树形菜单对象

    java实现树形菜单对象

    这篇文章主要为大家详细介绍了java实现树形菜单对象,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • springboot+mybatis如何屏蔽掉mybatis日志

    springboot+mybatis如何屏蔽掉mybatis日志

    这篇文章主要介绍了springboot+mybatis如何屏蔽掉mybatis日志问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • java&javascript自定义加密数据传输代码示例

    java&javascript自定义加密数据传输代码示例

    这篇文章主要介绍了java&javascript自定义加密数据传输代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • 一文搞懂Runnable、Callable、Future、FutureTask及应用

    一文搞懂Runnable、Callable、Future、FutureTask及应用

    一般创建线程只有两种方式,一种是继承Thread,一种是实现Runnable接口,在Java1.5之后就有了Callable、Future,这二种可以提供线程执行完的结果,本文主要介绍了Runnable、Callable、Future、FutureTask及应用,感兴趣的可以了解一下
    2023-08-08
  • SpringCloud将Nacos作为配置中心实现流程详解

    SpringCloud将Nacos作为配置中心实现流程详解

    这篇文章主要介绍了Springcloud中的Nacos Config服务配置,本文以用户微服务为例,进行统一的配置,结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • java实现联机五子棋

    java实现联机五子棋

    这篇文章主要为大家详细介绍了java实现联机五子棋,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java for循环和foreach循环的性能对比分析

    Java for循环和foreach循环的性能对比分析

    这篇文章主要介绍了Java for循环和foreach循环的性能对比分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论