多线程中FutureTask的使用

简介及需求背景

FutureTask可用于异步获取执行结果或取消执行任务的场景。通过get()方法可以异步获取执行结果,不论FutureTask调用多少次run()或者call()方法,它都能确保只执行一次Runable或Callable任务。因此,FutureTask非常适合用于耗时高并发的计算,另外可以通过cancel()方法取消执行任务。

多任务计算案例

直接上代码,注释写的很清楚

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author 沉鱼
 * @date 2017/12/17 12:50
 */
public class FutureTaskDemo {
    public static void main(String[] args) throws InterruptedException {
        //用于收集任务
        List> futureTasks = new ArrayList<>();
        //创建线程池
        ExecutorService pool = Executors.newFixedThreadPool(5);
        for (int i = 1; i <= 10; i++) {
            FutureTask futureTask = new FutureTask<>(new ComputeTask(i + ""));
            futureTasks.add(futureTask);
            //提交任务到线程池
            pool.submit(futureTask);
        }
        System.out.println("所有任务提交完毕,主线程接着执行");
        System.out.println("主线程打DOTA2中。。。。");
        //睡眠5秒,模拟主线程执行其他逻辑
        Thread.sleep(5000);
        System.out.println("主线程DOTA2游戏结束,开始统计任务执行结果");
        //用于打印任务执行结果
        Integer result = 0;
        for (FutureTask task : futureTasks) {
            try {
                //FutureTask的get()方法会自动阻塞,知道得到任务执行结果为止
                result += task.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        //关闭线程池
        pool.shutdown();
        System.out.println("多线程多任务执行结果:" + result);
    }

}
class ComputeTask implements Callable {
    //任务名称,方便查看
    private String taskName;

    public String getTaskName() {
        return taskName;
    }

    public void setTaskName(String taskName) {
        this.taskName = 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 <= 100; i++) {
            result = +i;
        }
        System.out.println("子线程任务" + taskName + "执行完成");
        return result;
    }
}

运行main()方法后,在控制台会打印如下结果:

创建子线程计算任务开始,任务名称:1
创建子线程计算任务开始,任务名称:2
创建子线程计算任务开始,任务名称:3
创建子线程计算任务开始,任务名称:4
创建子线程计算任务开始,任务名称:5
创建子线程计算任务开始,任务名称:6
创建子线程计算任务开始,任务名称:7
创建子线程计算任务开始,任务名称:8
创建子线程计算任务开始,任务名称:9
创建子线程计算任务开始,任务名称:10
所有任务提交完毕,主线程接着执行
主线程打DOTA2中。。。。
子线程任务1执行完成
子线程任务2执行完成
子线程任务6执行完成
子线程任务7执行完成
子线程任务8执行完成
子线程任务9执行完成
子线程任务10执行完成
子线程任务3执行完成
子线程任务4执行完成
子线程任务5执行完成
主线程DOTA2游戏结束,开始统计任务执行结果
多线程多任务执行结果:1000

后记

有关概念的简介,我不会做过多介绍,因为网上百度资料很多很齐全,自己讲的话没有百度的全,也没有那么多时间。

你可能感兴趣的:(java笔记)