1、FutureTask计算通过Callable实现,等价于一个可携带结果的Runnable,并有3个状态:等待、运行和完成。完成包括所有计算以任意的方式结束,包括正常结束、取消和异常。
2、一旦FutureTask进入完成状态,会永远停止在这个状态。
3、Future.get的行为依赖于任务的状态。如果已经完成,get得到返回结果。否则被阻塞直到任务转入完成状态,然后返回结果或抛出异常。
4、下例为一个提前开始代价昂贵计算:
以上程序单独开了一个线程进行loadProductInfo,当需要loadProductInfo时,可调用get返回这些数据,如果这些数据还没准备好,get将阻塞或抛出异常。
在Preloader中,如果get抛出一个ExecutionException,有3种原因:
1)Callable抛出受检查的异常,或是一个RuntimeException,或是一个Error。
2)使用launderThrowable方法封装复杂的异常处理逻辑。
public static RuntimeException launderThrowable(Throwable t){
if (t instanceof RuntimeException) return (RuntimeException) t;
else if ( t instanceof Error) throw (Error)t;
else throw new IllegalStateException("Not unchecked",t);
}
2、一旦FutureTask进入完成状态,会永远停止在这个状态。
3、Future.get的行为依赖于任务的状态。如果已经完成,get得到返回结果。否则被阻塞直到任务转入完成状态,然后返回结果或抛出异常。
4、下例为一个提前开始代价昂贵计算:
public class preloader{
private final FutureTask<ProductInfo> future=
new FutureTask<ProductInfo> (new Callable<ProductInfo>(){
public ProductInfo call() throws DataLoadException{
return loadProductInfo();
}
});
private final Thread thread=new Thread(future);
public void start(){thread.start();}
public ProductInfo get() throws DataLoadException,InterruptedException{
try{
return future.get();
}catch(ExecutionException e){
Throwable cause=e.getCause();
if (cause instanceof DataLoadException)
throw (DataLoadException) cause;
else
throw launderThrowable(cause);
}
}
}
以上程序单独开了一个线程进行loadProductInfo,当需要loadProductInfo时,可调用get返回这些数据,如果这些数据还没准备好,get将阻塞或抛出异常。
在Preloader中,如果get抛出一个ExecutionException,有3种原因:
1)Callable抛出受检查的异常,或是一个RuntimeException,或是一个Error。
2)使用launderThrowable方法封装复杂的异常处理逻辑。
public static RuntimeException launderThrowable(Throwable t){
if (t instanceof RuntimeException) return (RuntimeException) t;
else if ( t instanceof Error) throw (Error)t;
else throw new IllegalStateException("Not unchecked",t);
}