Well the oracle example is self-explanatory here. First one is this:
List<String> l = new ArrayList<>(Arrays.asList("one", "two"));
Stream<String> sl = l.stream();
l.add("three");
String s = l.collect(Collectors.joining(" "));
If you change l
by adding one more elements to it before you call the terminal operation (Collectors.joining
) you are fine; but notice that the Stream
consists of three elements, not two; at the time you created the Stream via l.stream()
.
On the other hand doing this:
List<String> list = new ArrayList<>();
list.add("test");
list.forEach(x -> list.add(x));
will throw a ConcurrentModificationException
since you can't change the source.
And now suppose you have an underlying source that can handle concurrent adds:
ConcurrentHashMap<String, Integer> cMap = new ConcurrentHashMap<>();
cMap.put("one", 1);
cMap.forEach((key, value) -> cMap.put(key + key, value + value));
System.out.println(cMap);
What should the output be here? When I run this it is:
{oneoneoneoneoneoneoneone=8, one=1, oneone=2, oneoneoneone=4}
Changing the key to zx
(cMap.put("zx", 1)
), the result is now:
{zxzx=2, zx=1}
The result is not consistent.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…