前言
文章
- 相关系列:《Java ~ Executor【目录】》(持续更新)
- 相关系列:《Java ~ Executor ~ Future【源码】》(学习过程/多有漏误/仅作参考/不再更新)
- 相关系列:《Java ~ Executor ~ Future【总结】》(学习总结/最新最准/持续更新)
- 相关系列:《Java ~ Executor ~ Future【问题】》(学习解答/持续更新)
- 涉及内容:《Java ~ Executor【总结】》
一 Future(未来)接口源码及机制详解
类
Future(未来)可以代表任务,作为与任务进行交互的入口,用于追踪/获取任务的执行状态/结果。我们可以将未来理解为任务的载体,其内部关联着任务,代码中具体表现为实现类会组合Runnable(可运行)变量来持有任务的引用。正是因为任务本身存在于未来的内部(即封装),因此未来很轻松的对任务执行过程进行观察和干涉。事实上未来接口也确实定义了诸多方法,令开发者可以对原本被封闭的任务执行过程进行干预,例如取消、状态判断及获取结果等。
/**
* A {@code Future} represents the result of an asynchronous computation. Methods are provided to check if the computation
* is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using
* method {@code get} when the computation has completed, blocking if necessary until it is ready. Cancellation is performed
* by the {@code cancel} method. Additional methods are provided to determine if the task completed normally or was cancelled.
* Once a computation has completed, the computation cannot be cancelled. If you would like to use a {@code Future} for the
* sake of cancellability but not provide a usable result, you can declare types of the form {@code Future<?>} and return
* {@code null} as a result of the underlying task.
* 一个未来代表一个异步计算。方法提供检查计算是否完成,等待计算完成并检索计算结果。结果只能当计算完成时使用get()方法
* 回收,必要时会阻塞直到它准备好(即完成计算)。取消通过cancel()方法执行。如果任务已完成,方法可额外确定任务是正常或
* 取消。一旦计算完成,则这个计算不可以再取消。如果您想要使用未来来实现可取消性,但不提供可用的结果,则可以声明
* Future<?>并返回null作为底层任务的结果。
* <p>
* <b>Sample Usage</b> (Note that the following classes are all made-up.)
* 简单使用(注意以下所有的类都是捏造的。)
* <pre> {@code
* interface ArchiveSearcher {
* String search(String target);
* }
* class App {
* // 执行器服务
* ExecutorService executor = ...
* // 档案搜查者
* ArchiveSearcher searcher = ...
* void showSearch(final String target) throws InterruptedException {
* // 递交一个任务,并获得一个Future
* Future<String> future = executor.submit(new Callable<String>() {
* public String call() {
* // 返回查询结果。
* return searcher.search(target);
* }});
* displayOtherThings(); // do other things while searching
* try {
* displayText(future.get()); // use future
* } catch (ExecutionException ex) {
* cleanup();
* return;
* }
* }
* }}</pre>
* <p>
* The {@link FutureTask} class is an implementation of {@code Future} that implements {@code Runnable}, and so may be
* executed by an {@code Executor}. For example, the above construction with {@code submit} could be replaced by:
* 未来任务类是可运行接口的的未来接口的实现,因此可被执行器执行。例如,上层submit()的结构可以被替换为:
* <pre> {@code
* // 将一个Callable任务封装为FutureTask任务,FutureTask是Runnable的子类,因此相当于转化为Runnable任务。
* FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
* public String call() {
* return searcher.search(target);
* }});
* // 执行FutureTask任务,相当于执行Runnable任务。
* executor.execute(future);
* }</pre>
* <p>
* Memory consistency effects: Actions taken by the asynchronous computation <a href="package-summary.html#MemoryVisibility">
* <i>happen-before</i></a> actions following the corresponding {@code Future.get()} in another thread.
* 内存一致性影响:异步计算所执行的操作发生在另一个线程中相应的Future.get()之后的操作之前。
*
* @param <V> The result type returned by this Future's {@code get} method
* @author Doug Lea
* @Description: 未来接口
* @see FutureTask
* @see Executor
* @since 1.5
*/
public interface Future<V> {
...
}
二 方法
- boolean cancel(boolean mayInterruptIfRunning) —— 取消 —— 取消当前未来代表任务,取消成功则返回true;否则返回false。当代表任务结束(完成/异常/取消)时,由于已处于最终状态,代表任务将无法被取消,方法会返回false;而如果代表任务未结束(完成/异常/取消),则当『mayInterruptIfRunning @ 如果运行可能中断』为false时方法将阻止等待中的代表任务执行;而如果参数为true,则方法还将取消执行中的代表任务,即使代表任务可能无法响应取消。而只要取消操作(阻止/取消)成功执行,无论最终的结果如何,方法都将返回true。
可以发现的是,cancel(boolean mayInterruptIfRunning)方法更多关注的是取消相关操作是否可以执行/是否成功执行(由于取消只能单次执行,因此并发可能导致失败),而并不关注取消相关操作执行后对代表任务的实际影响结果,特别是关于代表任务中断的部分。这实际上Java自身特性决定的,因为响应式中断的原因,代表任务的中断结果是无法预估的。这也就是说,只要取消相关操作可以成功执行,则无论代表任务最终的取消结果如何,其都会转变为取消状态。
/**
* Attempts to cancel execution of this task. This attempt will fail if the task has already completed, has already been cancelled,
* or could not be cancelled for some other reason. If successful, and this task has not started when {@code cancel} is called,
* this task should never run. If the task has already started then the {@code mayInterruptIfRunning} parameter determines
* whether the thread executing this task should be interrupted in an attempt to stop the task.
* 尝试取消任务的执行。如果任务已完成、已取消或者因为其它原因而无法被取消,则此次尝试将失败。如果成功,并且这个任务在
* cancel()方法调用时没有开始,那这个任务应该永远不会运行。如果这个任务已经开始那么mayInterruptIfRunning参数确定执行这个
* 任务的线程是否应该在这次尝试停止任务中断【即如果mayInterruptIfRunning参数为false,则cancel()方法只负责阻止等待中的任务
* 执行,否则还会负责取消执行中的任务,即中断执行中任务的线程】。
* <p>
* After this method returns, subsequent calls to {@link #isDone} will always return {@code true}. Subsequent calls to
* {@link #isCancelled} will always return {@code true} if this method returned {@code true}.
* 方法返回之后,随后调用isDone()方法将永远返回true。如果当前方法返回true,则随后调用isCancelled()方法将永远返回true。
*
* @param mayInterruptIfRunning {@code true} if the thread executing this task should be interrupted; otherwise, in-progress
* tasks are allowed to complete
* 如果线程正在执行的任务应该中断则为true,否则允许进行中的任务完成。
* @return {@code false} if the task could not be cancelled, typically because it has already completed normally; {@code true}
* otherwise
* 如果任务无法取消则为false,通常是因为任务已经正常完成;否则为true。
* @Description: 名称:取消
* @Description: 作用:取消当前未来所关联的任务。如果任务已结束(完成/异常/取消),由于已经处于最终状态,因此对于该类任
* @Description: 务将无法被取消;而对于非结束任务,如果mayInterruptIfRunning(如果运行可能中断)参数为false,则方法只会阻
* @Description: 止等待中的任务执行;如果为true,则方法还会尝试取消正在执行中的任务,虽然任务可能无法被取消。如果任务被
* @Description: 成功取消则返回true;否则返回false。
* @Description: 逻辑:从理论上来说,方法的返回值会匹配以下几种情况(只是理论上,具体还是看子类的具体实现):
* @Description: 已结束(完成/异常/取消):任务已结束,无法被取消,返回false;
* @Description: 等待中:任务会被阻止执行,返回true;
* @Description: 执行中 — 不取消(false):任务会正常/异常的直接结束,返回false;
* @Description: 执行中 — 要取消(true) — 无法/失败响应:任务无法响应取消或响应取消失败,返回false;
* @Description: 执行中 — 要取消(true) — 成功响应:任务会被成功取消,返回true;
*/
boolean cancel(boolean mayInterruptIfRunning);
- boolean isCancelled() —— 是否取消 —— 判断当前未来代表任务是否取消,是则返回true;否则返回false。
/**
* Returns {@code true} if this task was cancelled before it completed normally.
* 如果任务在正常完成之前取消则返回true。
*
* @return {@code true} if this task was cancelled before it completed 如果任务在正常完成之前取消则返回true
* @Description: 名称:是否取消
* @Description: 作用:判断当前未来所关联的任务是否取消,是则返回true;否则返回false。
* @Description: 逻辑:~
*/
boolean isCancelled();
- boolean isDone() —— 是否结束 —— 判断当前未来代表任务是否结束(完成/异常/取消),是则返回true;否则返回false。
/**
* Returns {@code true} if this task completed.
* 如果任务已经完成返回true。
* <p>
* Completion may be due to normal termination, an exception, or cancellation -- in all of these cases, this method will return
* {@code true}.
* 完成可能由于正常的终止、异常或取消,对于这些所有的情况方法都会返回true。
*
* @return {@code true} if this task completed 如果任务已经完成返回true
* @Description: 名称:是否结束
* @Description: 作用:判断当前未来所关联的任务是否结束(完成/异常/取消),是则返回true;否则返回false。
* @Description: 逻辑:~
*/
boolean isDone();
- V get() —— 获取 —— 获取当前未来代表任务的执行结果,在代表任务未结束(完成/异常/取消)之前,方法会无限等待。而根据代表任务最终状态的不同,方法会返回正常的执行结果,或抛出执行异常(代表任务自身执行时出现的异常)、取消异常(代表任务因cancel(boolean mayInterruptIfRunning)方法而被取消)及中断异常(采用非cancel(boolean mayInterruptIfRunning)方法的方式中断执行代表任务的线程)。
/**
* Waits if necessary for the computation to complete, and then retrieves its result.
* 必须等待计算完成才能回收结果。
*
* @return the computed result 计算结果
* @throws CancellationException if the computation was cancelled
* 取消异常:如果计算已被取消
* @throws ExecutionException if the computation threw an exception
* 执行异常:如果计算抛出一个异常
* @throws InterruptedException if the current thread was interrupted while waiting
* 中断异常:如果当前线程在等待中被中断
* @Description: 名称:获取
* @Description: 作用:获取当前未来所关联任务的执行结果,在任务没有完成之前,方法会一直阻塞。根据任务最终状态的不同,方
* @Description: 法会抛出取消异常(cancel()方法成功)、执行异常(任务执行时出现异常)及中断异常(采用非cancel()方法的方式
* @Description: 中断执行任务的线程)。
* @Description: 逻辑:~
*/
V get() throws InterruptedException, ExecutionException;
- V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException —— 获取当前未来代表任务的执行结果,在代表任务未结束(完成/异常/取消)之前,方法会有限等待指定时间,超出指定等待时间将抛出超时异常。而根据代表任务最终状态的不同,方法会返回正常的执行结果,或抛出执行异常(代表任务自身执行时出现的异常)、取消异常(代表任务因cancel(boolean mayInterruptIfRunning)方法而被取消)及中断异常(采用非cancel(boolean mayInterruptIfRunning)方法的方式中断执行代表任务的线程)。
/**
* Waits if necessary for at most the given time for the computation to complete, and then retrieves its result, if available.
* 必须在指定的时间范围内等待计算完成才能回收结果(如果有的话)
*
* @param timeout the maximum time to wait 用于等待的最大限度时间
* @param unit the time unit of the timeout argument 超时参数的时间单位
* @return the computed result 计算结果
* @throws CancellationException if the computation was cancelled
* 取消异常:如果计算已被取消
* @throws ExecutionException if the computation threw an exception
* 执行异常:如果计算抛出一个异常
* @throws InterruptedException if the current thread was interrupted while waiting
* 中断异常:如果当前线程在等待中被中断
* @throws TimeoutException if the wait timed out 如果等待超时
* @Description: 名称:获取
* @Description: 作用:在指定等待时间内获取当前未来所关联任务的执行结果。如果在指定等待时间内任务没有完成,则抛出超时
* @Description: 异常。根据任务最终状态的不同,方法还会抛出取消异常(cancel()方法成功)、执行异常(任务执行时出现异常)
* @Description: 及中断异常(采用非cancel()方法的方式中断执行任务的线程)。
* @Description: 逻辑:~
*/
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;