【发布时间】:2018-04-26 09:48:28
【问题描述】:
我不确定 lambda 在实践中是如何工作的,而且我很担心,因为在某些情况下,如果你不正确地使用 lambda,它们可能会导致诸如 ConcurrentModificationExceptions 之类的错误,这似乎表明存在竞争条件。
考虑下面的代码。
private class deltaCalculator{
Double valueA;
Double valueB;
//Init delta
volatile Double valueDelta = null;
private void calculateMinimum(List<T> dataSource){
dataSource.forEach((entry -> {
valueA = entry.getA();
valueB = entry.getB();
Double dummyDelta;
dummyDelta = Math.abs(valueA - valueB);
if(valueDelta == null){
setDelta(dummyDelta);
}else {
setDelta((valueDelta > dummyDelta) ? dummyDelta : valueDelta);
}
}));
}
private void setDelta(Double d){
this.valueDelta = d;
}
}
forEach 循环如何运作?不同的调用是否会传递到 JVM 认为合适的不同线程,从而导致出现可能导致不正确的最小值计算的竞争条件的可能性?
如果不是,为什么 forEach lambda 会抛出 ConcurrentModificationException?
【问题讨论】:
-
我看不出是什么导致了 ConcurrentModificationException ,你确定没有其他地方可以修改同一个
List<T> dataSource对象吗? -
我并不是说在这种情况下您可以获得 CME,但是如果您尝试在 forEach 中从集合中删除元素等操作,则会抛出 CME。
-
啊,好的。然后 +1 到 berry120 回答。这里不涉及多线程,只要您不使用
list.parallelStream().forEach之类的东西,就会同步调用 lambda - 但可能会产生误导的是,我们通常(有时错误地)将“并发”一词与多线程相关联。
标签: java lambda thread-safety