0

According to Javadoc, Future.get(), throws TimeoutException and CancellationException along with 2 others.

Whats the difference between TimeoutException and CancellationException?

From what i know, CancellationException is thrown when the thread timed-out and thus the executor cancelled it. But then when is TimeoutException thrown? is there a case that the timed-thread timed-out and not cancelled?

saw CancellationException when using ExecutorService and What is the best way to handle an ExecutionException? ampng others.

TIA.

//---------------

UPDATE

does nayone else call Future.cancel() unless the developer explicitly does?

javadoc isn't mentioning anything about CancellationException caused by it.

i've got a code coming into the system and i may have to cancel that code due to certain time-limit. 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. Future.isDone()or any other of its methods are of no help.

Community
  • 1
  • 1
ash__999
  • 169
  • 1
  • 1
  • 8

3 Answers3

4

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 CancellationExceptions.

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.

John Bollinger
  • 121,924
  • 8
  • 64
  • 118
  • thx for the useful answer. i've got more behind this Q-- failed to ut it all down before. pls see my update. – ash__999 Dec 19 '16 at 23:33
  • @ash__999, I've updated my answer to respond to your additions to the question, but please be aware that we frown on such question updates here. This is not a discussion -- once you receive an answer to your question, any followup question ought to be posed as new questions, preferrably referencing the original. – John Bollinger Dec 28 '17 at 17:23
1

CancellationException is thrown when the task is cancelled, by calling cancel().

TimeoutException is thrown when you ask get() to wait for a given time for the result, and the result takes more than that time to be produced.

A thread doesn't time out. And an executor doesn't cancel threads.

JB Nizet
  • 633,450
  • 80
  • 1,108
  • 1,174
0

From what i know, CancellationException is thrown when the thread timed-out and thus the executor cancelled it.

No, not quite. If thread A is calling future.get() and another thread B calls future.cancel() then the future.get() throws CancellationException for thread A. The exception is trying to tell thread A that the job that it was waiting for was canceled.

But then when is TimeoutException thrown? is there a case that the timed-thread timed-out and not cancelled?

No. If thread A calls future.get(long, TimeUnit), the method throws TimeoutException when the specified timeout expires. It does not mean that the running job timed outm just that the thread A that was waiting for the job to finish timed out. The future is most likely still running.

does anyone else call Future.cancel() unless the developer explicitly does?

Uh this is highly situation dependent. It is somewhat unusual for someone else aside from the thread that started the jobs to call future.cancel(...) but certainly not unheard of.

I've got a code coming into the system and i may have to cancel that code due to certain time-limit. 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.

future.cancel(...) returns true if the job was canceled. To quote from the javadocs:

Returns: false if the task could not be cancelled, typically because it has already completed normally; true otherwise

So if it returns true then the job successfully was canceled. You can make sure by calling future.get() afterwards which should throw CancellationException.

It is also very important to realize that threads can't be canceled easily if they are already running. Even if you call future.cancel(true), this only interrupts the thread which doesn't stop it immediately. It will cause Thread.sleep(...) and other methods that throw InterruptedException to throw but typically you have to write code to obey the interrupt flag. Something like:

// keep running until we are interrupted
while (!Thread.currentThread.isInterrupted()) {
    ...
}
Gray
  • 108,756
  • 21
  • 270
  • 333