在循环上创建线程

时间:2014-01-22 17:47:39

标签: java multithreading

我是线程新手,因此我想了解在循环中创建一堆Thread时幕后发生的事情以及影响/更好的方法。

以下是一个例子:

for (Page page : book) {
    Thread t = new Thread(new Runnable() {
        public void run() {
            //http request to get page and put into concurrent data structure
        }
    });
    t.start();
    threads.add(t);
}
//wait for threads

正如您可能已经看到的那样,在我的特定用例中,我正在通过HTTP寻呼我请求的对象。我知道这里不一定需要线程,而是我可以发出异步请求,但是如何(解释)如何改进它。

1 个答案:

答案 0 :(得分:3)

在您的示例中,您正在为书中的每个Page对象创建并启动新主题。如果您的系统上的页数多于核心数,则此功能无效。

现在直接创建和启动线程并跟踪它们也是一种低级别。

更好的解决方案是使用ExecutorService并创建一些线程,例如,关闭系统上的核心数量(对于您可能想要创建更多的I / O绑定任务)线程比:你可以看看这个答案下面的评论。)

例如:

final ExecutorService e = 
    Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

for (Page page : book) {
    e.submit( new Runnable() {
              //http request to get page and put into concurrent data structure}
}

然后等待ExecutorService终止其工作。

请注意,根据您从中获取信息的服务器,您可能需要额外添加延迟,以免过多地“破坏”服务器。

某些网站会告诉您查询它们的频率(例如Bitstamp比特币交换允许每秒一次查询),如果您不尊重延迟,将禁止您的IP。其他人不会对你有什么好处,如果他们发现你的呼吸过快就会禁止你的IP。