我正在为一个网站编写解析器,它有很多页面(我称它们为 IndexPages)。每个页面都有很多链接(一个 IndexPage 中大约有 300 到 400 个链接)。我使用 Java 的 ExecutorService
在一个 IndexPage 中同时调用 12 个 Callables
。每个 Callable
只是向一个链接发出一个 http 请求,并执行一些解析和数据库存储操作。当第一个 IndexPage 完成时,程序继续到第二个 IndexPage,直到找不到下一个 IndexPage。
运行时,似乎还可以,我可以很好地观察线程的工作/调度。每个链接的解析/存储只需要大约 1 到 2 秒。
但随着时间的推移,我观察到每个 Callable
(解析/存储)花费的时间越来越长。以这张照片为例,有时需要 10 秒或更长时间才能完成 Callable
(绿色条为 RUNNING,紫色条为 WAITING)。我的 PC 停滞不前,一切都变得迟钝。
这是我的主要算法:
ExecutorService executorService = Executors.newFixedThreadPool(12);
String indexUrl = // Set initial (1st page) IndexPage
while(true)
{
String nextPage = // parse next page in the indexUrl
Set<Callable<Void>> callables = new HashSet<>();
for(String url : getUrls(indexUrl))
{
Callable callable = new ParserCallable(url , … and some DAOs);
callables.add(callable);
}
try {
executorService.invokeAll(callables);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (nextPage == null)
break;
indexUrl = nextPage;
} // true
executorService.shutdown();
该算法简单且不言自明。我想知道是什么导致了这种情况?无论如何要防止这种性能下降?
CPU/内存/堆显示合理使用。
环境,仅供引用。
====================更新了====================
我已将我的实现从 ExecutorService
更改为 ForkJoinPool
:
ForkJoinPool pool=new ForkJoinPool(12);
String indexUrl = // Set initial (1st page) IndexPage
while(true)
{
Set<Callable<Void>> callables = new HashSet<>();
for(String url : for(String url : getUrls(indexUrl)))
{
Callable callable = new ParserCallable(url , DAOs...);
callables.add(callable);
}
pool.invokeAll(callables);
String nextPage = // parse next page in this indexUrl
if (nextPage == null)
break;
indexUrl = nextPage;
} // true
它比 ExecutorService
的解决方案花费的时间更长。 ExecutorService
完成所有页面大约需要 2 小时,而 ForkJoinPool
需要 3 小时,并且每个 Callable 仍然需要越来越长的时间来完成(从 1 秒到 5,6 或甚至 10 秒)。我不介意它需要更长的时间,我只希望完成一项工作需要恒定的时间(不是越来越长)。
我想知道是否在解析器中创建了很多(非线程安全的)GregorianCalendar
、Date
和 SimpleDateFormat
对象导致一些线程问题。但我没有重用这些对象或在线程之间传递它们。所以我还是找不到原因。
最佳答案
根据堆,您有内存问题。 ExecutorService.invokeAll
将 Callable
实例的所有结果收集到一个 List
中,并在它们全部返回时返回该 List
完全的。您可能想考虑简单地调用 ExecutorService.submit
,因为您似乎并不关心每个 Callable
的结果。
关于java - ExecutorService 变慢,使我的电脑陷入困境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20625792/