FutureTask——-Java中异步任务类的详细说明

来源:互联网 发布:wps软件下载2016 编辑:程序博客网 时间:2024/06/05 19:27

直接看下面的实验,注释详细:



package com.tbc.java;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.FutureTask;public class FutureTaskAndExecutor {   /**    * 个人对FutureTask<T> 的理解: FutureTask<T>从字面上可以理解为:异步任务类。 FutureTask<T>好比一个Map,    *  FutureTask<T> 中存放的是任务和该任务结束后返回的结果。可以理解为一个键值对(任务,任务的结果)    *  当任务 加入到FutureTask的对象的时候  任务的结果此时为空,另外FutureTask的一个对象只能一次性添加一个任务。    *  这个任务可以理解为实现Callable接口的类对象,要实现Callable接口的call方法,也就是说我们可以把我们要做的操作放在call方法里。    *  FutureTask<T>中的泛型指的是   call方法的返回值的实际类型即  return sum中sum 的类型。    *  FutureTask中有个get()方法,当调用该方法时,获取到的值是 call方法中返回的值,    *  get()方法只有在计算完成时获取,否则会一直阻塞直到任务转入完成状态,然后会返回结果或者抛出异常。     *      *      *  自己的疑问:我在下面做了一个实验,做了一个for循环验证了get()方法确实是阻塞的,既然是一直阻塞的,那么将get放在主线程中调用,不会出现问题吗?    *  这个get到底如何调用才是比较好的方法呢?本人尚未理解透彻,若有不通见解,请留言评论。    */    /**     * 本例子中加入了线程池的操作,将异步任务加入到线程池,将一些耗时的操作放入线程中操作,主线程还可以做些别的事情     */public static void main(String[] args) {List<FutureTask<Integer>> list =new ArrayList<FutureTask<Integer>>();/** * 创建线程池,线程池的大小和List.size没有啥必然的关系,一般的原则是<=list.size,多出来浪费不好 */ExecutorService exec = Executors.newFixedThreadPool(5);  //创建线程池,线程个数为5个for(int i =0; i <10; i++) {/** * 创建对象  */FutureTask<Integer> ft =new FutureTask<Integer>(new GetSum(i));/** * 添加到list,方便后面取得结果 */list.add(ft);/** *  一个个提交给线程池,当然也可以一次性的提交给线程池,exec.invokeAll(list); */exec.submit(ft);}// 开始统计结果Integer total = 0;for(FutureTask<Integer> ft : list){try {System.out.println("在get执行前,total:-----》"+total);System.out.println("在get执行前,时间:-----》"+new Date());total = total + ft.get();System.out.println("在get执行后,total:------》"+total);System.out.println("在get执行后,时间:------》"+new Date());} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}// 处理完毕,一定要记住关闭线程池,这个不能在统计之前关闭,因为如果线程多的话,执行中的可能被打断exec.shutdown();System.out.println("多线程计算后的总结果是:" + total);}}class GetSum implements Callable {private Integer total;private Integer sum = 0;public GetSum(Integer total){this.total = total;}public Object call() throws Exception {sum=total+1;System.out.println(Thread.currentThread().getName() + " sum:" + sum);for (int i = 0; i < 1500000000L; i++) {}return sum;}}


原创粉丝点击