一、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内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!