Java:ExecutorService和Callables:Timeout:future.get()导致程序直接中断
我在Java中使用Executor服务,我注意到一个我不理解的行为。 我使用Callable,当我调用我的线程(实现Callable的类)时,我设置了一个超时。然后我用Java:ExecutorService和Callables:Timeout:future.get()导致程序直接中断,java,multithreading,timeout,executorservice,callable,Java,Multithreading,Timeout,Executorservice,Callable,我在Java中使用Executor服务,我注意到一个我不理解的行为。 我使用Callable,当我调用我的线程(实现Callable的类)时,我设置了一个超时。然后我用future.get()等待结果,然后我想用future.isDone()检查任务执行过程中是否出现超时 正如我在invokeAll with timeout的文档中所读到的:返回表示任务的未来列表,其顺序与迭代器为给定任务列表生成的顺序相同。如果操作未超时,则每个任务都已完成。如果超时,其中一些任务将无法完成。 所以我想,如果超
future.get()
等待结果,然后我想用future.isDone()
检查任务执行过程中是否出现超时
正如我在invokeAll with timeout的文档中所读到的:返回表示任务的未来列表,其顺序与迭代器为给定任务列表生成的顺序相同。如果操作未超时,则每个任务都已完成。如果超时,其中一些任务将无法完成。
所以我想,如果超时发生,或者超时没有发生,我会得到这两种情况下的未来结果列表
现在发生的情况如下:当超时发生时,代码在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!
}
试试看{
//启动所有线程
结果=pool.invokeAll(线程,3,时间单位:秒);
用于(未来:结果)
{
尝试
{
//此方法会一直阻塞,直到收到结果为止,除非存在
//超时设置。
最后一个字符串rs=future.get();
if(future.isDone())
{
//如果future.isDone()=true,则未发生超时。
//做点什么
}
其他的
{
//超时
//记录下来,做点什么
打破
}
}
捕获(执行例外)
{
//记录消息并中断,这是一个片段!
}
捕获(中断异常例外)
{
//日志消息和中断,这是一个片段!
}
}
}
捕获(中断异常例外)
{
//日志消息,这是一个片段!
}
最后
{
//当超时发生时,代码从future.get()直接跳到这一点!
}
有人能给我解释一下,为什么我不能访问future.isDone()
,我应该做些什么才能识别超时
谢谢大家! 我不确定您是否正确使用了
invokeAll
。javadoc说:
执行给定的任务,返回保存任务的未来列表
全部完成或超时过期时的状态和结果,以
先发生。Future.isDone()对于
返回的列表
那么调用
isDone
有什么意义呢,因为对于所有返回的期货isDone
都是真的?您没有捕获到CancellationException
,这很可能是在调用get
后抛出的。请注意,此异常扩展了RuntimeException,编译器不会警告您捕获它
阅读以下文件:
执行给定的任务,当所有任务完成或超时过期时(以先发生的为准),返回一个保留其状态和结果的未来列表。Future.isDone()对于返回列表的每个元素都为true。返回时,未完成的任务将被取消
使用已取消。如果为false,则表示没有超时。然后,如果任务没有超时,但由于任何其他原因(如空指针、断言等)出现异常,您可以调用get()并捕获executionException。如果您没有忽略异常,您可能会理解发生了什么。您如何得出我忽略它们的结论???这只是一个片段!!!我更新了我的示例。您的代码片段忽略了异常,并且您接受了一个解释抛出了CancellationException的答案,但您没有看到它。这意味着这个异常被忽略了。当然我有代码,这只是一个片段!!!我够不到挡块。我有日志消息来检查它,并对它进行了调试。您是否希望
将来出现异常。get
会引发异常?文档中说:如果操作没有超时,每个任务都将完成。如果它确实超时,其中一些任务将无法完成。
正如我所想,Future.isDone()检查是否完成,我认为如果超时,它将返回false。看来我看错了,不可能。IDE说我的代码中从来没有抛出TimeoutException。谢谢!!!我真的不知道。现在,当我捕获这个CancellationException时,它的工作方式与预期的一样。现在我可以捕获这个超时异常,我不再需要future.isDone(),对吗?如果发生超时,它将永远不会到达这一点,如果没有超时,isDone()在任何情况下都将返回true,对吗?对。谢谢你的帮助!