gpt4 book ai didi

java - SynchronizedMap 并发修改异常

转载 作者:搜寻专家 更新时间:2023-11-01 02:00:44 25 4
gpt4 key购买 nike

我试图理解 SynchronizedMap 并运行了以下代码。我得到以下输出,但有一个异常(exception)。根据我的理解,当线程仍在映射上执行写入或线程处于 sleep 状态时,get() 方法试图访问同步映射时会导致异常。我的理解正确还是我遗漏了什么?

class MapHelper1 implements Runnable {
Map<String, Integer> map;

public MapHelper1(Map<String, Integer> map) {
this.map = map;
new Thread(this, "MapHelper1").start();
}

public void run() {
map.put("One", 1);
try {
System.out.println("MapHelper1 sleeping");
Thread.sleep(100);
} catch (Exception e) {
System.out.println(e);
}

}
}

class MapHelper2 implements Runnable {
Map<String, Integer> map;

public MapHelper2(Map<String, Integer> map) {
this.map = map;
new Thread(this, "MapHelper3").start();
}

public void run() {
map.put("two", 1);
try {
System.out.println("MapHelper2 sleeping");
Thread.sleep(100);
} catch (Exception e) {
System.out.println(e);
}

}
}


class MapHelper3 implements Runnable {
Map<String, Integer> map;

public MapHelper3(Map<String, Integer> map) {
this.map = map;
new Thread(this, "MapHelper3").start();
}

public void run() {
map.put("three", 1);
try {
System.out.println("MapHelper3 sleeping");
Thread.sleep(100);
} catch (Exception e) {
System.out.println(e);
}

}
}

public class MainClass {

public static void main(String[] args) {
Map<String, Integer> hashMap = new HashMap<>();
Map<String, Integer> syncMap = Collections.synchronizedMap(hashMap);
MapHelper1 mapHelper1 = new MapHelper1(syncMap);
MapHelper2 mapHelper2 = new MapHelper2(syncMap);
MapHelper3 mapHelper3 = new MapHelper3(syncMap);



for (Map.Entry<String, Integer> e : syncMap.entrySet()) {
System.out.println(e.getKey() + "=" + e.getValue());
}

}

}

输出:

MapHelper1 sleeping
MapHelper2 sleeping
MapHelper3 sleeping


Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1494)
at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1527)
at java.base/java.util.HashMap$EntryIterator.next(HashMap.java:1525)
at MainClass.main(MainClass.java:137)
Command exited with non-zero status 1

编辑:当输出无一异常(exception)地生成时,我再次运行代码几次。为什么会出现这种行为?

最佳答案

迭代时不同步访问。使用:

synchronized(syncMap) {
for (Map.Entry<String, Integer> e : syncMap.entrySet()) {
System.out.println(e.getKey() + "=" + e.getValue());
}
}

它甚至在 synchronizedMap() 中方法 javadoc

It is imperative that the user manually synchronize on the returned map when iterating over any of its collection views:

  Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // Needn't be in synchronized block
...
synchronized (m) { // Synchronizing on m, not s!
Iterator i = s.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}

关于java - SynchronizedMap 并发修改异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48323357/

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