Runnable作为线程的接口已经广为大家所知。
但是在执行任务的时候如果想要返回结果怎么办?如果想抛出异常怎么办?
这些都是Runnable无法做到的。这时候另一个线程接口就出现了: Callable:
V call() throws Exception;
Oh,perfect! 可以返回值,可以抛异常!
我们知道Runnable是通过Thread 类来执行的:new Thread(new Runnable(){..}).start();
那么Callable呢?
这个是通过RunnableFuture来执行的(当然RunnableFuture也可以用来执行Runnable)。
RunnableFuture的一个常用子类是:FutureTask.
下面的代码演示了这几个接口的用法:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
@SuppressWarnings("unchecked")
public class TestTask {
private FutureTask<String> task=new FutureTask(new Callable(){
public String call() throws Exception {
return "hello";
}
}
);
private ExecutorService exeService=Executors.newFixedThreadPool(4);
public static void main(String args[]){
TestTask test=new TestTask();
test.testFuture();
test.testExecutor();
}
public void testFuture(){
task.run();
String result="";
try {
result = task.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("task returns :"+result);
}
public void testExecutor(){
exeService.execute(task);
String result="";
try {
result = task.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("task submmited and run:"+result);
}
}
细心的看官可能已经发现了,这里面用到了另一个类:ExecutorService.
这是java concurrent执行框架的一部分。
这个框架包含了Executor(能执行Runnable),ExecutorService(Executor的子类,加强了对Runnable生命周期的管理),Executors(Executor和ExecutorService的工厂方法).在上面是通过Executors的静态方法产生一个
ThreadPoolExecutor来执行Runnable.