From what i know, CancellationException
is thrown when the thread timed-out and thus the executor cancelled it.
No. CancellationException
is thrown if the Future
's cancel()
method is invoked before the task completes, and either of its get()
methods is subsequently invoked.
But then when is TimeoutException thrown?
TimeoutException
(not CancellationException
) is thrown by Future.get(long, Timeunit)
if the specified amount of time passes without the task completing.
is there a case that the timed-thread timed-out and not cancelled?
Yes. Timing out is not at all the same thing as being cancelled.
Regarding the update:
does nayone else call Future.cancel()
unless the developer explicitly does?
Only someone who has a reference to the particular Future
in question can invoke its cancel()
method. The ExecutorService
does not invoke it, if that's what you mean, and in particular, a timeout differs from a cancellation and therefore does not cause CancellationException
s.
javadoc isn't mentioning anything about CancellationException
caused by it.
The Javadoc for Future.cancel()
does not mention it, nor do I see a particular need for it to do so. The exception's own class-level javadocs explain its significance, and the javadocs of those methods of Future
that can throw it document that they do.
i've got a code coming into the system and i may have to cancel that code due to certain time-limit.
So it sounds like you would invoke the two-arg version of Future.get()
so as to specify a time limit, and then in the event of a timeout (signaled by a TimeoutException
) you would invoke Future.cancel()
.
but then, i gotta be able to tell when Future.cancel()
returns true
, it did so because the task is completed or it is cancelled. From what it seems, Future.cancel()
is returning true in both of these cases.
Where do you get that? The docs of Future.cancel()
, which you yourself referenced, say that the method returns
false
if the task could not be cancelled, typically because it has already completed normally; true
otherwise
Thus, if Future.cancel()
returns true
then you can be confident that the task whose eventual result is represented by the Future
has successfully been cancelled, in the sense that no result will ever be produced, and that subsequent invocation of one of its get()
methods will throw a CancellationException
. If it had not yet been started then it never will be; if it had been started, then it was interrupted.
The latter alternative requires passing true
to Future.cancel()
, and in that case, the task actually stopping depends on its implementation having that response to its thread being interrupted. It is unclear whether cancellation of an in-progress task is considered successful if the task does not actually stop running; this may in fact be implementation-dependent.