循环Java中的常量线程数

时间:2012-12-20 18:56:56

标签: java multithreading

我正在使用Java中的线程编写应用程序,并且我在循环中保持常量线程数有问题(新线程使用新数据传入)。 我使用ExecutorService来限制线程数,但我遇到了启动新线程的问题。

我有类似的东西:

ExecutorService execDownload = Executors.newFixedThreadPool(5);
UniqList<String> documentList = new UniqList<String>("startfile.txt");
        Future<UniqList<String>> future;
        while( !execDownload.isShutdown()) {
            future = execDownload.submit(new Parser(documentList.get(i)));
            i++;
            try {
                documentList.addAll(future.get());
            } catch (InterruptedException | ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

Parser是一个可调用对象,它返回UniqList。我将此列表中的元素添加到我的全局列表中,该列表是所有文档名称的集合。 问题是: 我想要同时运行恒定数量的解析器。如果我在程序启动之前知道文档的所有名称就会很简单,因为我应该调用ExecutorService的submit()方法,即100次,如果我有100个文件名,但我不知道文件的所有名称 - 名称通过调用此代码进行解析:

new Parser(documentList.get(i))

并且名称在文件内。 所以还有一次问题 - 当新数据到达时如何保持线程的常数?在上面的代码中,我只有一个Future Object,这是我认为最大的问题 - 我应该创建一系列期货吗?但是后来如何检测来自ExecutorService的某个线程刚刚返回一些新数据......

算法应该是(我认为):

  1. 使用初始参数(第一个文档名称)启动程序
  2. 列表项
  3. 通过将其提交到ExecutorService并从起始文件
  4. 中提取所有文档名称来启动Parser类
  5. 将文档名称从#2添加到全局文档名称列表
  6. 使用全局文档名称List中的名称创建另一个Threads并解析文档。启动最大线程数(受ExecutorService限制)。解析每个下一个文件并从中提取新文件名
  7. 将#3中的名称添加到全局文档名称列表中 回到#4
  8. 正如你所看到的那样,就像递归一样。我认为这与解析网站,1个开始节点,第一级类别,第二级文章等相同。

    链接或示例代码非常有用。谢谢。

2 个答案:

答案 0 :(得分:0)

您的代码几乎是顺序的:future.get()会阻塞,直到任务完成,因此只要前一个任务正在运行,您就无法提交新任务。你可以:

  • 在一个循环中提交N个任务并存储期货然后尝试在未来调用get on并提交新任务
  • 但那将重新发明轮子:CompletionService似乎完全符合你的需要。

答案 1 :(得分:0)

我建议放弃未来,并构建Parser来了解执行者:

execDownload.submit(new Parser(execDownload, documentList.get(i)));

让Parser将此“execDownload”ExecutorService存储为成员变量。

在Parser.run()结束时,当您拥有新解析的文档名称列表时,可以为它们创建新的解析器,并安排它们:

foreach (String newDoc: UniqList)
{
     execDownload.submit(new Parser(execDownload, newDoc));
}