I'm currently trying to understand how FutureTask.cancel(true)
is working, this is the relevant piece of official doc
If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
And this is the implementation of cancel
taken from Github
public boolean cancel(boolean mayInterruptIfRunning) {
if (!(state == NEW &&
UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // in case call to interrupt throws exception
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if (t != null)
t.interrupt();
} finally { // final state
UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
}
}
} finally {
finishCompletion();
}
return true;
}
So, basically we can see that the only thing that cancel(true)
is doing is calling interrupt
on the worker thread. So, what if the call
method of my FutureTask
looks like something like this
SomeType call() {
for(int i = 0; i < 1000000000; i++) {
//pass
}
return someValue;
}
So, my question - do I have to add manual check for thread interruption in order to be able to cancel FutureTasks of such type ? I mean it seems to be obvious because I'm not calling any IO function can handle interrupt and not checking Thread.currentThread().isInterrupted()
, so this task seems to be no cancelable, but still this is not mentioned in any official doc that we have to handle interrupts or self to be able to cancel the task so it still better to ask others opinion.
There's no pre-emptiveness in Java. For anything to be interruptable, it has to cooperate. So yes, the task must check if it's been interrupted or else it will run till the end despite the future being cancelled. Disappointing, I know.