I am learning Callables and decided to make a very simple program. The problem is that the Thread is blocked when I call getFutureTask(); Thread.State: TIMED_WAITING (on object monitor)
Could you please tell me why is it so and why does my program work when I write futureTask.run() before futureTask.get(); I do understand that get() method waits and returns result. but can't understand what method run() does. I do appreciate your answers a lot!
public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
FutureTask futureTask = getFutureTask(1);
System.out.println(futureTask.get());
}
public static FutureTask<Integer> getFutureTask(Integer i) {
return new FutureTask<Integer>(() -> i*45);
}
run
vs get
run
is the method that actually starts the execution of the task. It is supposed to be called in a different thread, for example by an ExecutorService
.
get
will not trigger execution, it just waits until the task is done, i.e. until run
is finished. This obviously implies that you call run
somehow before or from a different thread.
ExecutorService
and CompletableFuture
FutureTask
is not really supposed to be used directly by a user. It is more the type of class that is used behind the curtain in order to realize a nice async-API. More specifically, it is the base implementation for Future
, as for example returned by ExecutorService
when you spawn tasks with it.
Instead you should look into ExecutorService
ExecutorService service = Executors.newCachedThreadPool();
...
Future<Integer> task = service.submit(() -> i * 45);
...
Integer result = task.get();
and CompletableFuture
CompletableFuture<Integer> task = CompletableFuture.supplyAsync​(() -> i * 45);
...
Integer result = task.get();
for an easy to use interface to spawn async tasks.
CompletableFuture
s have the advantage that you can also setup a pipeline of operations that are all executed asynchronously once the previous operation has finished. So for example:
CompletableFuture<Void> task = CompletableFuture.supplyAsync(Foo::readSomeFile)
.thenApplyAsync(Foo::validateData)
.thenApplyAsync(Foo::compressData)
.thenAcceptAsync(Foo::uploadData);