转自《编程思想》
Runnable是执行工作的独立任务,但是它不返回任何值。如果你希望任务在完成时能够返回一个值,那么可以实现Callable接口而不是Runnable接口。在Java SE5中引入的Callable是一个具有类型参数的泛型,它的泛型参数表示的是从方法call()(而不是run())中返回的值,并且必须使用ExecutorService.sunmit()方法调用它,以下是一个简单的例子:
class TaskWithResult implements Callable<String>{
private int id;
public TaskWithResult(int id){
this.id = id;
}
public String call(){
return "result of TaskWithResult " + id;
}
}
public class CallableDemo{
public static void main(String[] args){
ExecutorService exec = Executors.newCachedThreadPool();
ArrayList<Future<String>> results = new ArrayList();
for(int i = 0; i < 10; i++){
results.add(exec.submit(new TaskWithResult()));
}
for(Future<String> fs : results){
try{
//打印代码
}catch(){
//处理异常
}finally{
exec.shutdown();
}
}
}
}
submit()方法会产生Future对象,它用Callable返回结果的特定类型进行了参数化。你可以用isDone()方法来查询Future是否已经完成,当任务完成时,它具有一个结果,你可以调用get()方法来获取结果,你也可以不用isDone()进行检查就直接调用get(),在这种情况下,get()将阻塞,直至结果准备就绪,你还可以在试图调用get()来获取结果前,先调用具有超时的get()或者isDone()来查看任务是否完成。