Reputation: 1112
I was reading some javadoc and I came across this example from ThreadPoolExecutor.afterExecute(...)
javadocs:
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);
}
}
Can anybody explain me how the code can pass the first if. I mean how r
can be instanceof Future<?>
?
Upvotes: 0
Views: 800
Reputation: 116918
Can anybody explain me how the code can pass the first if. I mean how r can be instanceof Future?
You are correct to be confused. It is somewhat strange code that passes in a Runnable
and then tries to cast it to a Future
which doesn't extend Runnable
. It's not a pattern you see often. This is in the javadocs for ThreadPoolExecutor.afterExecute(...)
javadocs and after looking at the code, the r
argument to the method is the task that has finished.
I think the code would be a lot more clean if it was a FutureTask
instead of a Future
. FutureTask
is even mentioned right above the sample code in the javadocs:
When actions are enclosed in tasks (such as {@link FutureTask})...
FutureTask
implements RunnableFuture
which is both a Runnable
and a Future
so the code works but using FutureTask
would be less confusing.
Upvotes: 2