I have the following test code.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
class MyTask extends FutureTask<String>{
@Override
protected void done() {
System.out.println("Done");
}
public MyTask(Runnable runnable) {
super(runnable,null);
}
}
public class FutureTaskTest {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
FutureTask<String> future = new MyTask(new Runnable() {
public void run() {
System.out.println("Running");
}
});
executor.submit(future);
try {
future.get();
} catch (Exception ex ) {
ex.printStackTrace();
}
executor.shutdownNow();
}
}
This works fine - the overridden 'done' methond in MyTask is called when the task is done. But how does the executor know how to call that ?
The executor only have these submit methods:
public <T> Future<T> submit(Callable<T> task);
public Future<?> submit(Runnable task);
Internally it seems 'submit' wraps the callable/runnable in a new FutureTask(). As far as the executor is concerned I've submitted a Runnable or Callable - from what I gather from these 2 signatures. How does it know I submitted a FutureTask and know how to call my overridden done() ?
Method submit extends base method Executor. execute(java. lang. Runnable) by creating and returning a Future that can be used to cancel execution and/or wait for completion.
When one submit a task to ExecutorService which is take a long running time, then it returns a Future object immediately. This Future object can be used for task completion and getting result of computation.
If the task is complete, it will return true; otherwise, it returns false. The method that returns the actual result from the calculation is Future. get(). We can see that this method blocks the execution until the task is complete.
Future is a base interface and defines the abstraction of an object which promises results to be available in the future while FutureTask is an implementation of the Future interface.
From the executor's point of view, you've submitted a Runnable
task. The run
method of this task (implemented by FutureTask
) is what calls done
at the appropriate time. The executor doesn't make any direct call to done
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With