简体   繁体   English

FutureTask中的awaitDone抛出InterruptedException

[英]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? 我已经在网上搜索了一个星期,但是没有类似TimeoutException之后如何返回FutureTask的帖子 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 如果我运行此命令,有时(每1000个中的1个)

 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. 第83行是上述代码示例中显示的未来任务的result.get()。

Now my question is, can calling result.cancel(true) in future cause InterruptedException in result.get? 现在我的问题是,将来调用result.cancel(true)会导致result.get中的InterruptedException吗? 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.. AFAIK result.get()与执行我要取消的已提交任务的线程不同。

From the Javadoc: 从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. 如果成功,并且在调用cancel时此任务尚未开始,则该任务永远不要运行。 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. 如果任务已经开始,则mayInterruptIfRunning参数确定是否应中断执行该任务的线程以尝试停止该任务。

After this method returns, subsequent calls to isDone() will always return true. 此方法返回后,对isDone()后续调用将始终返回true。 Subsequent calls to isCancelled() will always return true if this method returned true. 如果此方法返回true,则随后对isCancelled()调用将始终返回true。

So if mayInterruptIfRunning is set, then yes, it will attempt to interrupt the thread running the task. 因此,如果设置了mayInterruptIfRunning则为是,它将尝试中断运行任务的线程。

In other words, .cancel(true) will attempt to interrupt a running task, and .cancel(false) won't. 换句话说, .cancel(true)将尝试中断正在运行的任务,而.cancel(false)则不会。

It sounds as though result.get() will still get interrupted if you call .cancel(false) and the task hasn't even started. 听起来如果您调用.cancel(false) ,结果result.get()仍然会被中断,而任务甚至还没有开始。

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. 尽管他们正在捕获从服务器抛出的中断异常,但是由于服务器使用动态代理,因此将其包装在UndeclaredThrowableException下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM