Reputation: 1021
Please consider the following code:
public static void main(String... args) throws InterruptedException, ExecutionException {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> future =
executor.scheduleAtFixedRate(Dummy::iterate,
0,
1,
TimeUnit.SECONDS);
TimeUnit.MILLISECONDS.sleep(1500);
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MILLISECONDS);
System.out.println("Getting the future...");
future.get();
System.out.println("Got the future...");
System.out.println("Finished");
}
private static void iterate(){
System.out.println("Iterating... counter is: " + counter++);
try {
TimeUnit.MILLISECONDS.sleep(900);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Note that the executor.awaitTermination(...)
command future.get()
command are happening after 1500 ms, meaning in the middle of the iterate()
method.
This means that awaitTermination(...)
will return false because the scheduled task hasn't finsihed yet.
Now, future.get()
will wait forever. The task will finish and the service won't start other tasks, but yet the get()
will never return.
A workaround is asking the future for isDone()
, and only if it is done, asking for the result.
My question is what exactly is happening?
Looks like that if shutDown()
happens in the during an iteration, the ScheduledThreadPool will somehow halt and, meaning there will be no future available. So why is this happening? I have looked at the documentation but couldn't find any reference indicating this issue. Is it possible that such scenario causes a future to not done, and later for the future to not be available?
Upvotes: 4
Views: 2687
Reputation: 900
If you replace your :
future.get();
to something like:
future.get(2000,TimeUnit.MILLISECONDS);
Then you see java.util.concurrent.TimeoutException
exception ocuur.
and this Exception thrown when a blocking operation times out. Blocking operations for which a timeout is specified need a means to indicate that the timeout has occurred. For many such operations it is possible to return a value that indicates timeout; when that is not possible or desirable then TimeoutException should be declared and thrown.
Upvotes: 2