Callable
、Runnable
、Future
和FutureTask
做为java 线程池运行的重要载体,有必要深入理解。
Callable
和 Runnable
都是执行的任务的接口,区别在于Callable
有返回值,而Runnable
无返回值。
Future 表示异步任务返回结果的接口
RunnableFuture
继承了Runnable
, Future,表示可以带有返回值的run接口
FutureTask是一个实现类,实现了RunnableFuture
接口,既能接受Runnable类型的任务,也可以接受Callable
类型的任务,这个类的作用主要是 有一个protected void done()
方法用来扩展使用,作为一个回调方法。下面是一个例子:
import java.util.concurrent.Callable;
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;
public class FutureStudy {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newCachedThreadPool();
Future<?> runFuture = executor.submit(new MyRunTask());
Future<String> callFuture = executor.submit(new MyCallTask());
Future<?> taskFuture = executor.submit(new MyFutureTask());
System.out.println("任务全部提交成功,开始get 获取返回结果....... ");
Thread.sleep(3000);
System.out.println(runFuture.get());
System.out.println(callFuture.get());
System.out.println(taskFuture.get());
executor.shutdown();
}
static class MyFutureTask extends FutureTask<String> {
public MyFutureTask(){
this(new Callable<String>(){
@SuppressWarnings("unchecked")
@Override
public String call() throws Exception {
System.out.println(" FutureTask 线程执行完毕!~" );
return (String) "FutureTask 返回值!~";
}
});
}
public MyFutureTask(Callable<String> callable) {
super(callable);
}
@Override
protected void done() {
System.out.println("执行回调的done方法~");
}
}
static class MyCallTask implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(" callable 线程执行完毕!~" );
return "callable返回值";
}
}
static class MyRunTask implements Runnable {
@Override
public void run() {
System.out.println(" runnable 线程执行完毕!~, 无返回值" );
}
}
上面的代码和简单,分别使用了Callable、Runnable和FutureTask作为任务提交给线程池来执行。
而只有Callable类型的任务才有返回值。
我们看看ExecutorService.submit方法的内部实现,
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
由此可见,submit提交的任务都是转化为FutureTask来执行的。
下一篇文章来仔细分析FutureTask的源代码,请阅读 FutureTask源码分析