我正在阅读ThreadPoolExecutor.afterExecute()
并在此过程中发现了JDK中的示例代码,看起来像
class ExtendedExecutor extends ThreadPoolExecutor {
// ...
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future) {
try {
Object result = ((Future) r).get();
} catch (CancellationException ce) {
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null)
System.out.println(t);
}
}}
javadocs中的代码提及
r instanceof Future<?>
和
result = ((Future<?>) r).get()
从了解应该有 FutureTask 而不是Future。
r是一个Runnable,Future并没有实现Runnable,但是FutureTask在javadocs中提到了
如果有人可以帮我清理云,因为我在这里感到困惑。
答案 0 :(得分:1)
可以一次实现两个接口。如果Runnable
对象也实现了Future
,那么我们可以通过强制转换来对该对象进行特殊处理(在检查强制转换之后)。对于FutureTask<V>
个对象,这些对象同时实现Runnable
和Future<V>
,因此其中的逻辑将适用于它们。
编辑:不确定为什么选择downvote,但我认为这意味着我更好地澄清
FutureTask<String> f = new FutureTask(
() -> { System.out.println("Hey"); },
"Hi");
f instanceof Runnable; // true
f instanceof Future; // true
executor.submit(f);
// Executor will call afterExecute(f, null) after running f.
// Prints:
// Hey
// Hi
&#34;嗨&#34;是if
语句的内部,你不确定它是否被执行(假设我们正在为result
的值添加一个print语句,即){{ 1}})
答案 1 :(得分:0)
FutureTask实现了RunnableFuture,而RunnableFuture扩展了Runnable,Future,因此它是您发布FutureTask但可以转换为Future的原因
答案 2 :(得分:0)
我认为仅仅说Future
而不是FutureTask
背后的原因是,这是我们在这里接受的最普遍的事情。
虽然在实践中它很可能是FutureTask
,但
让我们说纯粹是为了一个例子r
是以下类的实例:
public class MyExample implements Runnable, Future {
....
}
afterExecute(r,t)
可以正常使用,但r
不是 FutureTask
的实例
答案 3 :(得分:0)
ThreadPoolExecutor.afterExecute(Runnable r,Throwable t) 如果你调用executor.execute()或者r可以是futureTask,则调用是executor.submit(),这里r可以运行。 FutureTask实现了RunnableFuture,后者又扩展了Runnable和Future
因此,在调用提交的情况下,intanceof适用于Runnable和Future。