I have this snippet.
final ExecutorService executor = Executors.newFixedThreadPool(3);
final Runnable runnable = ()->{System.out.println("Inside runnable run method");};
final Callable<String>callable = ()->{System.out.println("Inside callable call method");return "callable";};
final FutureTask<String> futureTask = new FutureTask<>(()->{System.out.println("CallableInFutureTask");},"JOHN");
final FutureTask f1 = (FutureTask)executor.submit(callable);
final FutureTask f2 = (FutureTask)executor.submit(futureTask);
final FutureTask f3 = (FutureTask)executor.submit(runnable);
System.out.println("f1 = " + f1+" "+f1.isDone()+" "+f1.get());
System.out.println("FutureTask Reference Object: "+futureTask.isDone()+" "+futureTask.get());
System.out.println("f2 = "+f2.isDone()+" "+f2.get());
System.out.println("f3 = " + f3+" "+f3.isDone()+" "+f3.get());
executor.shutdown();
The f1 and f3 Future variables is returning the correct values of its get method but the FutureTask past it to the Executors the f2 is returning null why is this? Even the futureTask reference is returning the correct value "JOHN" for the get method but why is this? Maybe because i am passing a FutureTask? I dont get it.
I just thought that f2 and futureTask references would return the same value. Sorry if this question is simple thanks a lot.
When you submit a FutureTask
to a ExecutorService
it is treated as a Runnable
so the the Future
you get from the submit
method would have the value null
as the Runnable
instances don't return any result.
Since the FutureTask
implements the Runnable
interface this method of the ExecutorService
is called submit(Runnable task)
so the Runnable
you are wrapping in the FutureTask
constructor is actually submitted to the ExecutorService
and hence you get null on the invocation of f2.get()
.
But when you are calling the get()
on the FutureTask
reference you are then getting back the value you supplied as the second parameter once the Runnable
has completed its execution (when you submitted the task earlier in the ExecutorService
).
You can also verify this by not submitting the futureTask
in the ExecutorService
, then if you try to invoke get on the futureTask
variable the get
call will block indefinitely as the Runnable
has not been executed.
// Returning "JOHN" when the supplied Runnable is completed execution.
System.out.println("FutureTask Reference Object: "+futureTask.isDone()+" "+futureTask.get());
This is as per the docs:
Creates a FutureTask that will, upon running, execute the given Runnable, and arrange that get will return the given result on successful completion.