我想重现一个场景,其中有两个线程访问共享的HashMap。当一个线程使用putAll()操作将共享映射的内容复制到localMap时,第二个线程会更改共享映射,并且应该抛出CocurrentModificationException。
我已尝试但无法在putAll操作运行时重现异常。每次putAll在其他线程进行修改之前完成或者在其他线程修改之后调用putAll。
有人可以建议我如何在java中生成场景?
感谢。
答案 0 :(得分:0)
旋转两个线程,让它们连续运行。
让一个线程不断地执行putAll,另一个线程不断地进行修改。
答案 1 :(得分:0)
import java.util.HashMap;
import java.util.Map;
public class Example {
private final HashMap<String, String> map = new HashMap<String, String>();
public static void main(String[] args) {
new Example();
}
public Example() {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
int counter = 0;
while (true) {
Map<String, String> tmp = new HashMap<String, String>();
tmp.put("example" + counter, "example");
counter++;
map.putAll(tmp);
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
map.values().remove("example");
}
}
});
thread1.start();
thread2.start();
}
}
不幸的是,我无法直接从当前工作站复制/粘贴正在运行的代码,因此我在此处重新输入,因此可能存在输入错误。
正如您所看到的,第一个线程不断添加值,而第二个线程迭代Map中的值。当它开始迭代值时,它需要许多值(该值在迭代器的构造中初始化)。但是,因为当Iterator在实际执行删除代码时检查映射中的实际值时,thread1会不断添加项,所以此值不是预期的。这会导致ConcurrentModificationException。
答案 2 :(得分:0)
如果您只需要抛出CocurrentModificationException
,那么您可以实施自己的Map
实施(HackedMap
),以便在{{1}时从HashMap
中删除项目尝试复制HashMap