Heisenberg
Heisenberg

Reputation: 5668

awaitDone in FutureTask throwing InterruptedException

I've been searching web for a week now but none of the posts like How do I get FutureTask to return after TimeoutException? seems to answer my question. I've extracted a code sample from my code:

 Future<Object> result = executorService.submit(new Callable<Object>() {
    @Override public Object call() throws Exception {
     ...........
    }
  });

  try {
    return result.get(timeout.getValue(), timeout.getUnit().getTimeUnit());
  } catch (TimeoutException e) {
    result.cancel(true);
    throw new TTimeoutException(e);
  }

If I run this, sometimes(1 out of 1000) I'm getting

 java.lang.InterruptedException
        at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:400)
        at java.util.concurrent.FutureTask.get(FutureTask.java:199)
        at com.abc.callers.A.call(A.java:83)

and line no:83 is result.get() of future task shown in above code sample.

Now my question is, can calling result.cancel(true) in future cause InterruptedException in result.get? If not, who can change the interrupt status of my current thread? AFAIK result.get() isn't the same thread as the one running my submitted task which I'm cancelling..

Upvotes: 1

Views: 5425

Answers (2)

Heisenberg
Heisenberg

Reputation: 5668

Thanks for your inputs everyone. After so much digging I finally found the answer.

This is a server side code and the fault was in client code who was interrupting server if it was not returning result in specified time limit. Of course client's time limit was less than server's timeout limit.

Although they were catching the interrupted exception thrown from server, but this was wrapped under UndeclaredThrowableException as server was using dynamic proxies.

Upvotes: 2

chiastic-security
chiastic-security

Reputation: 20520

From the Javadoc:

boolean cancel(boolean mayInterruptIfRunning)

Attempts to cancel execution of this task. This attempt will fail if the task has already completed, has already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. 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.

After this method returns, subsequent calls to isDone() will always return true. Subsequent calls to isCancelled() will always return true if this method returned true.

So if mayInterruptIfRunning is set, then yes, it will attempt to interrupt the thread running the task.

In other words, .cancel(true) will attempt to interrupt a running task, and .cancel(false) won't.

It sounds as though result.get() will still get interrupted if you call .cancel(false) and the task hasn't even started.

Upvotes: 2

Related Questions