Java FutureTask理解

来源:互联网 发布:程序员猝死 知乎 编辑:程序博客网 时间:2024/06/05 00:26

尊敬原创作者,转载请注明出处:

http://blog.csdn.net/gemmem/article/details/8956703

FutureTask是为了弥补Thread的不足而设计的,它可以让程序员准确地知道线程什么时候执行完成并获得到线程执行完成后返回的结果(如果有需要)。

java.util.concurrent
类 FutureTask<V>

java.lang.Object  继承者 java.util.concurrent.FutureTask<V>
类型参数:
V - 此 FutureTask 的 get 方法所返回的结果类型。
所有已实现的接口:
Runnable, Future<V>, RunnableFuture<V>

public class FutureTask<V>
extends Object
implements RunnableFuture<V>

可取消的异步计算。利用开始和取消计算的方法、查询计算是否完成的方法和获取计算结果的方法,此类提供了对 Future 的基本实现。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。

可使用 FutureTask 包装 CallableRunnable 对象。因为FutureTask 实现了Runnable,所以可将FutureTask 提交给Executor 执行。

除了作为一个独立的类外,此类还提供了 protected 功能,这在创建自定义任务类时可能很有用。

这个解释过于全面,没有突出重点,其实重点就在于FutureTask的get()方法。

先看一个demo:

import java.util.concurrent.ExecutionException;  import java.util.concurrent.ExecutorService;  import java.util.concurrent.Executors;  import java.util.concurrent.Future;  import java.util.concurrent.FutureTask;  import java.util.concurrent.Callable;  public class Main {      /**      * @param args      */      public static void main(String[] args) {        MyCall task1 = new MyCall("this is task1");        MyCall.Result result = new MyCall.Result();        result.setFlag("this is result");          ExecutorService pool = Executors.newFixedThreadPool(3);          Future f1 = new FutureTask(task1) {              @Override              protected void done() {                  try {                                      MyCall.Result r = (MyCall.Result) get();                                        System.out.println(r.getFlag() + " about callable");                  } catch (InterruptedException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  } catch (ExecutionException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  }                  super.done();              }            };          Future f2 = new FutureTask(new MyRun(),result){              @Override              protected void done() {                  try {                                      MyCall.Result r = (MyCall.Result) get();                                          System.out.println(r.getFlag() + " about runnable");                  } catch (InterruptedException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  } catch (ExecutionException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  }                  super.done();              }          };          pool.execute((Runnable) f1);          pool.execute((Runnable) f2);      }    }  class MyCall implements Callable {      Result r;      String j = "";      MyCall() {        }        MyCall(String flag) {          j = flag;      }      @Override      public Result call() throws Exception {          System.out.println("this is MyCall call");          r = new Result();          r.setFlag(j);          return r;      }        public static class Result {          private String flag = "";            public String getFlag() {              return flag;          }            public void setFlag(String flag) {              this.flag = flag;          }      }  }  class MyRun implements Runnable{        @Override      public void run() {          System.out.println("this is MyRun run");                }    }  

对代码做如下分析:

pool.execute((Runnable) f1)执行后,会创建一个线程,并执行MyCall的call方法,call方法执行完毕后,f1 实例的done()立即执行,这时候f1实例的get()方法会返回之前call()方法返回的Result实例。

pool.execute((Runnable) f2)的执行和f1类似,不同的是其中done()中的get()返回的实例是f2构造函数提供的。