【发布时间】:2020-07-15 20:29:30
【问题描述】:
我在 java 8 生命周期的早期就已经看到,嵌套并行流会导致死锁,我相信这个问题已经得到解决。他们还有其他可能出现的问题吗?我知道嵌套并行流不会带来那么高的性能,但它似乎仍然可以将我的速度提高大约 50%(将运行时间从 11 分钟减少到 5.5 分钟)。
当然,如果它导致问题,我宁愿放慢速度,但是搜索嵌套的并行流会返回早期的 1.8 问题,而不是当前的任何问题。
这里有一些简化的示例代码(它是为了使 80k 对象列表中的相对引用更容易跨系统传输。在实际代码中,有更多操作和更详细的异常尝试/捕获)-
LinkSystem(List<Obj>objList,String property){
objList.parallelstream
.filter(obj -> obj.getAttribute.equals(property))
.forEach(f->
{
try { Optional<Obj>MysteryObj = objList.parallelStream()
.filter(z->z.getAttribute2.equals(f.getAttribute3)
.findAny();
f.setAttribute4(z.MysteryObj.get().getID());
});
} catch(Exception e){e.printStackTrace();}
}
【问题讨论】:
-
您是在问死锁是一般情况下发生还是仅在指定代码中发生?
-
好吧,不是死锁 - 更多其他问题。我相信僵局问题已经解决。如果还可以的话,我想我现在应该已经看到了?如果给定代码可能导致并发问题、竞争条件、无用处理,则更多。 (我对嵌套并行流也很好奇,但我目前关心的是这个特定的代码)。
-
直觉上我没有发现问题。看起来你正在做只读的东西。如果您想自己解决问题,您可能需要研究并行流的实际工作方式。死锁或竞争条件不是像量子物理学那样随机发生的事情。有原因,例如错误的同步。您可以查看this 答案,以更深入地了解并行流的作用并从那里继续。
-
关键词是时间复杂度。您的嵌套迭代具有 二次 时间复杂度,并且将其除以恒定数量的 CPU 内核(在最佳情况下)不会改变这一点。首先创建从属性 2 到 obj 的映射并在第二次迭代中使用它具有 线性 时间复杂度,并且对于大型数据集运行速度明显更快,即使是顺序流也是如此。我猜,几秒钟而不是你的五分钟……
标签: java java-8 parallel-processing java-stream