Search code examples
javainterruptfuturetask

Do I have to manually process interrupt in FutureTask?


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.


Solution

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