尊敬原创作者,转载请注明出处:
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 Objectimplements RunnableFuture<V>
可取消的异步计算。利用开始和取消计算的方法、查询计算是否完成的方法和获取计算结果的方法,此类提供了对Future
的基本实现。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。
可使用 FutureTask 包装 Callable
或Runnable
对象。因为FutureTask 实现了Runnable,所以可将FutureTask 提交给 Executor
执行。
除了作为一个独立的类外,此类还提供了 protected 功能,这在创建自定义任务类时可能很有用。
这个解释过于全面,没有突出重点,其实重点就在于FutureTask的get()方法。
先看一个demo:
package base2; 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 Concurrent_FutureTask { /** * @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<MyCall.Result> f1 = new FutureTask<MyCall.Result>(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<MyCall.Result> f2 = new FutureTask<MyCall.Result>(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构造函数提供的。