我正在尝试从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}
,而不是我预期的remove(key, value)
。我的问题是:我如何实现理想的行为?迭代期间Map上的www.domain.com
方法是正确的选择吗?
答案 0 :(得分:0)
是的,您应该使用两个参数remove
方法。虽然迭代期间的直接收集变异对于大多数java集合来说通常都是坏事,但ConcurrentHashMap允许这样做。