public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}
public class FutureTask<V> implements RunnableFuture<V> {
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
sync = new Sync(callable);
}
public FutureTask(Runnable runnable, V result) {
sync = new Sync(Executors.callable(runnable, result));
}
....
public void run() {
if(this.state == 0 && UNSAFE.compareAndSwapObject(this, runnerOffset, (Object)null, Thread.currentThread())) {
boolean var9 = false;
try {
var9 = true;
Callable var1 = this.callable;
if(var1 != null) {
if(this.state == 0) {
Object var2;
boolean var3;
try {
var2 = var1.call();
var3 = true;
} catch (Throwable var10) {
var2 = null;
var3 = false;
this.setException(var10);
}
if(var3) {
this.set(var2);
var9 = false;
} else {
var9 = false;
}
} else {
var9 = false;
}
} else {
var9 = false;
}
} finally {
if(var9) {
this.runner = null;
int var6 = this.state;
if(var6 >= 5) {
this.handlePossibleCancellationInterrupt(var6);
}
}
}
this.runner = null;
int var12 = this.state;
if(var12 >= 5) {
this.handlePossibleCancellationInterrupt(var12);
}
}
}
}
如上提供了两个构造函数,一个以Callable为参数,另外一个以Runnable为参数。这些类之间的关联对于任务建模的办法非常灵活,允许你基于FutureTask的Runnable特性(因为它实现了Runnable接口),把任务写成Callable,然后封装进一个由执行者调度并在必要时可以取消的FutureTask。
FutureTask可以由执行者调度,这一点很关键。它对外提供的方法基本上就是Future和Runnable接口的组合:get()、cancel、isDone()、isCancelled()和run(),而run()方法通常都是由执行者调用,我们基本上不需要直接调用它。
public class OnlineShopping implements Callable<String> //,Runnable
{
private Knife knife;
@Override
public String call() throws Exception {
System.out.println("第一步:下单");
System.out.println("第二步:等待送货");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第三步:快递送到");
knife = new Knife();
return "快递ok";
}
public Knife getKnife() {
return knife;
}
}
public class MarketShopping implements Callable<String> //,Runnable
{
private Vegetable vegetable;
@Override
public String call() throws Exception {
System.out.println("第一步:去超市");
System.out.println("第二步:挑选蔬菜");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第三步:菜带回家");
vegetable = new Vegetable();
return "买菜完成ok";
}
public Vegetable getVegetable() {
return vegetable;
}
}
ArrayList<FutureTask<Integer>> callers = new ArrayList<FutureTask<Integer>>();
callers.add(futureTask);
callers.add(futureTask2);
//等待任务完成
for(FutureTask<Integer> temp:callers){
try {
temp.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
System.out.println("准备工作共用时" + (System.currentTimeMillis() - startTime) + "ms,开始展示厨艺");
cook(onlineShopping.getKnife(), marketShopping.getVegetable());
System.out.println("饭做好总共用时" + (System.currentTimeMillis() - startTime) + "ms");
}
public static void cook(Knife knife, Vegetable vegetables) {
try {
// 模拟做饭时间
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
第一步:下单
第二步:等待送货
第一步:去超市
第二步:挑选蔬菜
第三步:菜带回家
超市购物用时5020ms
第三步:快递送到
网上购物用时10016ms
准备工作共用时10017ms,开始展示厨艺
饭做好总共用时20018ms