并发包之FutureTask
FutureTask
Future接口和实现Future接口的FutureTask类,代表异步计算的结果.
简介
在Java中一般通过继承Thread类或者实现Runnable接口这两种方式来创建多线程,但是这两种方式都有个缺陷,就是不能在执行完成后获取执行的结果,因此Java 1.5之后提供了Callable和Future接口,通过它们就可以在任务执行完毕之后得到任务的执行结果。
Callable接口
对于需要执行的任务需要实现Callable接口,Callable接口定义如下:
1 | public interface Callable<V> { |
可以看到Callable是个泛型接口,泛型V就是要call()方法返回的类型。Callable接口和Runnable接口很像,都可以被另外一个线程执行,但是正如前面所说的,Runnable不会返回数据也不能抛出异常。
Future 接口
Future接口代表异步计算的结果,通过Future接口提供的方法可以查看异步计算是否执行完成,或者等待执行结果并获取执行结果,同时还可以取消执行。Future接口的定义如下:
1 | public interface Future<V> { |
- cancel():cancel()方法用来取消异步任务的执行。如果异步任务已经完成或者已经被取消,或者由于某些原因不能取消,则会返回false。如果任务还没有被执行,则会返回true并且异步任务不会被执行。如果任务已经开始执行了但是还没有执行完成,若mayInterruptIfRunning为true,则会立即中断执行任务的线程并返回true,若mayInterruptIfRunning为false,则会返回true且不会中断任务执行线程。
- isCanceled():判断任务是否被取消,如果任务在结束(正常执行结束或者执行异常结束)前被取消则返回true,否则返回false。
- isDone():判断任务是否已经完成,如果完成则返回true,否则返回false。需要注意的是:任务执行过程中发生异常、任务被取消也属于任务已完成,也会返回true。
- get():获取任务执行结果,如果任务还没完成则会阻塞等待直到任务执行完成。如果任务被取消则会抛出CancellationException异常,如果任务执行过程发生异常则会抛出ExecutionException异常,如果阻塞等待过程中被中断则会抛出InterruptedException异常。
- get(long timeout,Timeunit unit):带超时时间的get()版本,如果阻塞等待过程中超时则会抛出TimeoutException异常。
FutureTask
FutureTask 继承了RunnableFuture接口,RunnableFuture接口继承了Runnable接口和Future接口
所以FutureTask既能当做一个Runnable直接被Thread执行,也能作为Future用来得到Callable的计算结果。(目前我觉得是两个都是必须的,又作为runnable,又作为返回结果,都是必须的)
当作为Runnable时,有三种状态
- 未启动 FutureTask.run()方法还没有执行之前.
- 已启动 FutureTask.run()方法执行过程中
- 已完成 FutureTask.run()方法执行结束后
FutureTask主要使用get()和cancle()两个方法.
1 | public class FutureCallableDemo { |
Author: corn1ng
Link: https://corn1ng.github.io/2018/01/19/Java并发/并发包之FutureTask/
License: 知识共享署名-非商业性使用 4.0 国际许可协议