我在Java中使用ExecutorService,我注意到了一个我不理解的行为。
我使用Callable,当我调用我的线程(实现Callable的类)时,我设置了一个超时。然后我等待future.get()
的结果,之后我想检查future.isDone()
是否在执行任务期间发生超时。
正如我在有关超时的invokeAll文档中所读到的那样:returns a list of Futures representing the tasks, in the same sequential order as produced by the iterator for the given task list. If the operation did not time out, each task will have completed. If it did time out, some of these tasks will not have completed.
所以我想在两种情况下都会获得Future结果列表,如果超时发生,如果没有。
现在发生的情况如下:当发生超时时,代码不会在future.get()
之后继续进行,我无法确定是否可以检查future.isDone()
是否发生超时。我没有发现任何异常,我直接导致我的代码中的finally块,我真的不明白。
这是我的代码片段:
try {
// start all Threads
results = pool.invokeAll(threads, 3, TimeUnit.SECONDS);
for (Future<String> future : results)
{
try
{
// this method blocks until it receives the result, unless there is a
// timeout set.
final String rs = future.get();
if (future.isDone())
{
// if future.isDone() = true, a timeout did not occur.
// do something
}
else
{
// timeout
// log it and do something
break;
}
}
catch (ExecutionException e)
{
// log messages and break, this is a snippet!
}
catch (InterruptedException ex)
{
// log message and break, this is a snippet!
}
}
}
catch (InterruptedException ex)
{
// log message, this is a snippet!
}
finally
{
// when a timeout occurs, the code jumps from future.get() directly to this point!
}
有人可能会解释我,为什么我无法联系到future.isDone()
以及我应该改变什么才能识别超时?
谢谢!
答案 0 :(得分:6)
您没有抓住CancellationException
,这很可能在致电get
后被抛出。请注意,此异常扩展RuntimeException
,编译器不会警告您捕获它。
阅读invokeAll
的文档:
执行给定的任务,返回一个Futures列表,其中包含所有完成或超时到期时的状态和结果,以先发生者为准。对于返回列表的每个元素,Future.isDone()都为true。返回后,尚未完成的任务将被取消。
答案 1 :(得分:2)
我不确定您是否正确使用invokeAll
。 javadoc说:
执行给定的任务,返回持有他们的期货清单 所有完成或超时到期时的状态和结果,以较大者为准 首先发生。 Future.isDone()对于每个元素都是true 返回列表。
那么调用isDone
的重点是什么,因为所有返回的期货isDone
都是真的?
答案 2 :(得分:0)
使用isCancelled。如果为false,则表示没有超时。然后你可以调用get()并捕获executionException如果任务没有超时但由于任何其他原因(例如nullpointer,assert等)而有异常