在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
个流。
doSomething
:map.put(item1.key + " " + item2.key, item1.val + item2.val);
。
有序对的数量为n * (n - 1) / 2
,其中n
是列表的大小。我还考虑均匀分配工作量以达到负载平衡(此时假设每对的执行时间相同)。因此,不需要为每个有序对并行调用doSomething(item1, item2)
函数,但可能需要一组准备好的对。
答案 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
个可能对的集合,因此在这种情况下并行性可能更有效。