Callable
public interface Callable<V> {
V call();
}
Callable接口是jdk1.5新增的接口. 在此之前如果想得到其他线程的一个计算结果通常需要使用共享变量或其他线程通信方式, 而Callable可以理解为一个带返回值的多线程接口. 返回值类型由泛型V决定
和Runnable一样, 接口本身是什么都干不了的; 把一个Runnable对象转换为实际线程的类是Thread, 而负责Callable的类是FutureTask.
Future
public interface Future<V>
Future这个接口的大概意义是这样的——对于某个同步的计算过程, 我们不用关心它的进度; 当我们想拿到结果的时候, 如果计算完成则直接返回结果, 否则就等待那个线程完成计算.
但是为什么命名为"Future"呢...感觉上面这段的说明还不够...
Future声明的方法
//取消任务, 参数表示是否触发线程中断, 即interrupt方法
boolean cancel(boolean)
//是否被取消
boolean isCanceled()
//是否不再运行, 包括运行结束和中途取消等情况
boolean isDone()
//获得运行结果, 如果没有运行完则等待
V get()
//在一段时间内获得运行结果, 如果超时抛出TimeoutException异常
V get(long, timeUnit)
Future接口的实现
在jdk中有2个类实现了该接口, 分别是FutureTask和CompletableFuture. 后者有点麻烦也许以后有机会会提到吧.
FutureTask
public class FutureTask<V> implements RunnableFuture<V>
其中
public interface RunnableFuture<V> extends Runnable, Future<V>
RunnableFuture没有声明新的方法, 略去说明
FutureTask的构造方法
FutureTask有2种构造方法, 虽然参数类型的区别让我开始以为这是两种不同的形式, 但实际上是相同的.
//传入callable对象, FutureTask的get()方法相当于调用了call()方法(当然内部实现比较复杂)
public FutureTask(Callable<V> callable)
/*通过Executors.callable(runnable, result) 转化为上面的callable对象
这个构造方法的意义是在runnable运行结束后, 返回result,
*感觉这种形式完全可以用上面的方法替代啊...不太理解*/
public FutureTask(Runnable runnable, V result)
FutureTask的方法都来自于Runnable和Future, 没有添加新的方法.
FutureTask怎么用
就像Thread类一样, 构造一个Thread(Runnable)必须使用start()
方法才能运行这个线程, FutureTask也是如此. 但是这个类本身并没有定义一个启动方法.
其实这也是很显然的; 或者说FutureTask本身本就不应该定义一个启动的方法. 既然FutureTask继承了Runnable接口, 那就应该把它传入一个新线程, 即new Thread(futureTask).start()
, 不过根据实际情况, FutureTask对象通常是放在线程池中运行的.
网友评论