从Java8

时间:2015-08-03 21:08:07

标签: java list parallel-processing java-8 java-stream

Java8中,List<Item> list我按顺序处理它,如下所示:

ConcurrentMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
for (int i1 = 0; i1 < list.size() - 1; i1++) {
    Item item1 = list.get(i1);
    for (int i2 = i1 + 1; i2 < list.size(); i2++) {
        Item item2 = list.get(i2);
        doSomething(item1, item2);
    }
}

所以我处理列表中所有有序的项目对(item1的索引&lt; item2的索引)。现在,我想为每个有序对并行运行doSomething(item1, item2)函数。实现这一目标的最佳策略是什么?对最快的代码感兴趣。欢迎Java8个流。

例如

doSomethingmap.put(item1.key + " " + item2.key, item1.val + item2.val);

有序对的数量为n * (n - 1) / 2,其中n是列表的大小。我还考虑均匀分配工作量以达到负载平衡(此时假设每对的执行时间相同)。因此,不需要为每个有序对并行调用doSomething(item1, item2)函数,但可能需要一组准备好的对。

3 个答案:

答案 0 :(得分:5)

chrome.browserAction.onClicked.addListener(function(tab) {

  chrome.extension.sendRequest(active);

});

这并不像其他任何答案那样复杂。

答案 1 :(得分:1)

如果您不需要控制正在运行的线程数(即列表相对较小),您可以像这样并行运行它们:

for (int i1 = 0; i1 < list.size() - 1; i1++) {
    Item item1 = list.get(i1);
    for (int i2 = i1 + 1; i2 < list.size(); i2++) {
        Item item2 = list.get(i2);
        new Thread(){
            @Override
            public void run() {
                doSomething(item1, item2);
            }
        }.start();
    }
}

如果列表很长,上面的代码将为每对项目旋转一个线程,这可能会严重影响性能。在这种情况下,我会使用ExecutorService并创建一个newFixedThreadPool来限制可以同时跨越的线程数:

ExecutorService executor = Executors.newFixedThreadPool(5);

for (int i1 = 0; i1 < list.size() - 1; i1++) {
    Item item1 = list.get(i1);
    for (int i2 = i1 + 1; i2 < list.size(); i2++) {
        Item item2 = list.get(i2);

        executor.execute(new Runnable(){
            @Override
            public void run() {
                doSomething(item1, item2);
            }
        });

    }
}

答案 2 :(得分:1)

我已将特殊功能添加到我的StreamEx库(自版本0.3.6)以解决此问题:EntryStream.ofPairs方法:

EntryStream.ofPairs(list).parallel()
    .forKeyValue((item1, item2) -> doSomething(item1, item2));

如果您不介意使用第三方库,可以试试这个。在内部,它与公认的解决方案不同。它尽可能均匀地分割n*(n-1)/2个可能对的集合,因此在这种情况下并行性可能更有效。