Reputation: 11146
I am reading about ThreadPoolExecutor.afterExecute()
and in the process found example code in JDK which looks like
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);
}
}}
The code in the javadocs mentions
r instanceof Future<?>
and
result = ((Future<?>) r).get()
From Understanding there should be FutureTask instead of Future.
r is a Runnable and Future doesn't implement Runnable but FutureTask does and is mentioned in the javadocs
If any one can please help me clear the clouds as i am confused here.
Upvotes: 0
Views: 675
Reputation: 11
ThreadPoolExecutor.afterExecute(Runnable r, Throwable t) here r can be runnable in case u call executor.execute() or r can be a futureTask in case call is executor.submit(). FutureTask implements RunnableFuture which in turn extends Runnable and Future
So, intanceof holds true for Runnable and Future in case submit is called.
Upvotes: 1
Reputation: 822
I believe the reasoning behind just saying Future
instead of FutureTask
is that it's the most general thing we accept here.
Although in practice it most likely will be a FutureTask
, it doesn't have to be.
Let's say purely for the sake of an example that r
is an instance of the following class:
public class MyExample implements Runnable, Future {
....
}
The afterExecute(r,t)
will work just fine, but r
is not an instance of FutureTask
Upvotes: 0
Reputation: 742
It is possible to implement two interfaces at once. If the Runnable
object also implements Future
, then we can perform special handling of that object by casting it (after checking the cast will be fine). In the case of FutureTask<V>
objects, these implement both Runnable
and Future<V>
and so the logic there will apply to them.
Edit: Not sure why the downvote but I suppose that means I better clarify
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
The "Hi" is from the inside of the if
statement which you're unsure if it ever gets executed (assuming that we're adding a print statement to the value of result
, ie) f.get()
)
Upvotes: 1
Reputation: 1
FutureTask implements RunnableFuture,and RunnableFuture extends Runnable, Future,so it is the reseaon why you post FutureTask but can be cast to Future
Upvotes: 0