多线程中FutureTask的使用

来源:互联网 发布:数据dat文件打开工具 编辑:程序博客网 时间:2024/06/06 07:34

简介及需求背景

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<FutureTask<Integer>> futureTasks = new ArrayList<>();        //创建线程池        ExecutorService pool = Executors.newFixedThreadPool(5);        for (int i = 1; i <= 10; i++) {            FutureTask<Integer> 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<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);    }}class ComputeTask implements Callable<Integer> {    //任务名称,方便查看    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

后记

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

原创粉丝点击