2

我在 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.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()以及我应该改变什么才能识别超时?

谢谢!

4

3 回答 3

6

你没有接住CancellationException,很可能是在调用后被抛出get。请注意,此异常会扩展RuntimeException,编译器不会警告您捕获它。

阅读文档invokeAll

执行给定的任务,当全部完成或超时到期(以先发生者为准)时,返回保存其状态和结果的 Futures 列表。Future.isDone() 对于返回列表的每个元素都是 true。返回时,取消未完成的任务

于 2012-03-06T12:40:50.110 回答
2

我不确定您是否invokeAll正确使用。javadoc 说:

执行给定的任务,当全部完成或超时到期(以先发生者为准)时,返回保存其状态和结果的 Futures 列表。Future.isDone() 对于返回列表的每个元素都是 true。

那么,isDone既然所有返回的 FuturesisDone都是真的,那么调用的意义何在?

于 2012-03-06T12:38:19.883 回答
0

使用 isCancelled。如果为 false,则表示没有超时。然后您可以调用 get() 并捕获 executionException 如果任务没有超时但由于任何其他原因(如 nullpointer、assert 等)而出现异常

于 2016-08-05T23:57:49.097 回答