我正在用Java编写一个应用程序,它使用ExecutorService来运行多个线程。
我希望将多个任务(一次数千个)作为Callables提交给Executor,完成后,检索他们的结果。我接近这个的方式是每次调用submit()函数时,我得到一个存储在ArrayList中的Future。稍后我将List传递给一个不断迭代它的线程,调用future.get()函数并超时以查看任务是否完成。这是正确的方法还是效率太低?
编辑---更多信息--- 另一个问题是每个Callable需要不同的处理时间。因此,如果我只是从List中取出第一个元素并在其上调用get(),它将阻塞,而其他元素的结果可能变得可用而程序将无法知道。这就是为什么我需要继续迭代超时。
提前致谢
答案 0 :(得分:6)
这是正确的做法还是效率太低?
这本身并不正确。你不必要地迭代ArrayList
检查任务完成情况。
这很简单:只需使用:CompletionService。您可以轻松地将现有执行程序包装到其中。来自JavaDocs:
生产者提交执行任务。消费者完成任务 并按照他们完成的顺序处理他们的结果。
从本质上讲,CompletionService
提供了一种通过调用take()
简单地获得结果的方法。它是一个阻塞函数,调用者将阻塞,直到结果可用。
答案 1 :(得分:1)
请注意,对Future.get的调用将阻止,直到答案可用。所以你不需要另一个线程迭代数组列表。
请参阅此处https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6