【发布时间】:2015-12-27 22:27:58
【问题描述】:
我正在尝试从ConcurrentHashMap 中删除某些条目。然而,由于这发生在多线程环境中,因此可以在迭代进行时删除和/或修改条目。发生这种情况时,迭代器上的remove 方法将删除该条目,即使它在通过next 接收后已被修改。我构建了一个示例程序来说明这一点:
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
map.put("foo", "bar");
map.put("quz", "qaz");
CountDownLatch foundBar = new CountDownLatch(1);
CountDownLatch doneModifying = new CountDownLatch(1);
CountDownLatch doneIterating = new CountDownLatch(1);
new Thread(() -> {
try {
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
if (entry.getValue().equals("bar")) {
foundBar.countDown();
doneModifying.await();
it.remove();
}
}
doneIterating.countDown();
} catch (InterruptedException e) {
throw new Error(e);
}
}).start();
foundBar.await();
map.put("foo", "nob");
doneModifying.countDown();
doneIterating.await();
System.out.println(map);
输出将是{quz=qaz},而不是我预期的{quz=qaz,foo=nob}。我的问题是:如何实现所需的行为?迭代期间 Map 上的remove(key, value) 方法是正确的选择吗?
【问题讨论】:
标签: java concurrency java.util.concurrent concurrenthashmap