gpt4 book ai didi

java - 为什么并发修改会出现在这里

转载 作者:行者123 更新时间:2023-12-02 10:27:14 25 4
gpt4 key购买 nike

以下代码抛出并发修改异常

import java.util.*;

public class SampleTest
{
public static void main(String[] args) {

LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put("value1","a");
map.put("value2","b");
map.put("value3","c");
map.put("value4","d");
map.put("value5","e");

// sublists
List<LinkedHashMap<String, String>> subList = new ArrayList<>();
for(int i = 0; i<5; i++) {
subList.add(map);
}

List<List<LinkedHashMap<String, String>>> mainList = new LinkedList<>();
for(int i = 0; i<3; i++)
{
mainList.add(subList);
}

List<LinkedHashMap<String,String>> temp = mainList.get(mainList.size() - 1);
List<LinkedHashMap<String,String>> temp2 = mainList.get(mainList.size() - 2);
for(LinkedHashMap<String,String> map2 : temp) {
temp2.add(map); // Exception Thrown Here......
}
}
}

但是我通过创建一个新列表并添加 map 并最终在 temp2 的循环外部添加新列表来修复代码

example,
List<LinkedHashMap<String,String>> pp = new ArrayList<>();
for(LinkedHashMap<String,String> map2 : temp) {
pp.add(map);
}
temp2.addAll(pp);

我想详细了解为什么前面的代码会发生并发。

谢谢。

最佳答案

这段代码:

List<List<LinkedHashMap<String, String>>> mainList = new LinkedList<>();
for(int i = 0; i<3; i++)
{
mainList.add(subList);
}

正在向 mainList 添加 3 次 subList。当我说“三次”时,我的意思是代码实际上是添加同一个实例三次。您可以修改 mainList 任何有效索引处的元素,并且您将修改所有其他元素,因为它们是同一实例。请参阅this question ;它可能有助于这个概念。

因此,这段代码:

List<LinkedHashMap<String,String>> temp =  mainList.get(mainList.size() - 1);
List<LinkedHashMap<String,String>> temp2 = mainList.get(mainList.size() - 2);

从两个不同的索引中获取相同 List 并将其分配给两个不同的变量。换句话说,temp == temp2(引用相等)为true

然后,您使用 temp 变量迭代 List,同时使用 将元素添加到 List temp2 变量:

for(LinkedHashMap<String,String> map2 : temp) {
temp2.add(map); // Exception Thrown Here......
}

但是,temptemp2 引用相同 List。您的代码基本上执行以下操作:

List<Object> list = ...; // create new list and fill it
Object someObj = new Object();

for (Object obj : list) { // iterating list
list.add(someObj); // modifying list while it's being iterated
}
<小时/>

最终结果是您在迭代 List 的同时尝试修改它。 LinkedList(或者任何 Collection 的标准实现)都不允许这样做。来自 documentation :

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the Iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

如果您不知道,当循环目标是 Iterable 时,for-each 循环会在内部使用 Iterator

关于java - 为什么并发修改会出现在这里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53861409/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com