I try to make an API aysnchronous as:
Future<Integer> fASync(int x) {
return new FutureTask(() -> {
try {
Thread.sleep(new Random().nextInt(1, 3) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return x * x;
});
}
..then I try to use it:
Future<Integer> asyncCall = fASync(x);
asyncCall .get();
But this never completes and call just blocks.
Is this not correct way of making your API asynchronous?
You have declared a FutureTask
but haven't actually run it so a call to asyncCall.get()
will block forever.
Here is your example with extra logging and adding a step to execute the task in a new ExecutorService
.
static FutureTask<Integer> fASync(int x) {
System.out.println("fASync("+x+") called");
return new FutureTask<>(() -> {
System.out.println("fASync("+x+") FutureTask has started");
try {
Thread.sleep(new Random().nextInt(1, 3) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("fASync("+x+") FutureTask has ended");
return x * x;
});
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService exec = Executors.newFixedThreadPool(1);
FutureTask<Integer> task = fASync(5);
// MUST execute the task or task.get() will block forever
exec.execute(task);
System.out.println("task.get()="+task.get());
exec.shutdown();
exec.awaitTermination(1, TimeUnit.DAYS);
System.out.println("ENDED");
}
If you enable the exec.execute(task);
line it will print these messages and complete task.get()
, instead of printing the first line only and no response from task.get()
:
fASync(5) called
fASync(5) FutureTask has started
fASync(5) FutureTask has ended
task.get()=25
ENDED