我是Java 8的初学者。
无干扰对于获得一致的Java流行为非常重要。 想象一下,我们正在处理大量数据流并在此过程中 来源改变了。结果将是不可预测的。这是 不管流的并行处理模式如何 顺序的。
可以修改源,直到语句终端操作为止 调用。除此之外,在流之前不应修改源 执行完成。所以在流中处理并发修改 source对于获得一致的流性能至关重要。
上述引文取自here。
有人可以做一些简单的例子,说明为什么改变流源会产生如此大的问题吗?
答案 0 :(得分:8)
oracle example在这里是不言自明的。首先是:
List<String> l = new ArrayList<>(Arrays.asList("one", "two"));
Stream<String> sl = l.stream();
l.add("three");
String s = l.collect(Collectors.joining(" "));
如果您通过在之前添加一个元素来更改l
,则调用终端操作(Collectors.joining
)就可以了;但请注意Stream
由三个元素组成,而不是两个元素;当您通过l.stream()
创建了流。
另一方面这样做:
List<String> list = new ArrayList<>();
list.add("test");
list.forEach(x -> list.add(x));
会抛出ConcurrentModificationException
,因为您无法更改来源。
现在假设您有一个可以处理并发添加的基础源:
ConcurrentHashMap<String, Integer> cMap = new ConcurrentHashMap<>();
cMap.put("one", 1);
cMap.forEach((key, value) -> cMap.put(key + key, value + value));
System.out.println(cMap);
输出应该在这里?当我运行它时:
{oneoneoneoneoneoneoneone=8, one=1, oneone=2, oneoneoneone=4}
将密钥更改为zx
(cMap.put("zx", 1)
),结果现在为:
{zxzx=2, zx=1}
结果不一致。