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源码分析
本文详细介绍了Java线程池中的关键组件Callable、Runnable、Future及FutureTask的区别与联系,并通过实例展示了如何使用这些接口与类进行异步任务处理。

849

被折叠的 条评论
为什么被折叠?



