从 ConcurrentHashMap 中移除
Removing from a ConcurrentHashMap
我正在尝试从 ConcurrentHashMap
中删除某些条目。然而,由于这发生在多线程环境中,条目可能会在迭代过程中被删除 and/or 修改。发生这种情况时,迭代器上的 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上的方法是否是正确的选择?
是的,您应该使用两个参数 remove
方法。虽然在迭代期间直接改变集合对于大多数 java 集合来说通常是一件坏事,但 ConcurrentHashMap 允许这样做。
我正在尝试从 ConcurrentHashMap
中删除某些条目。然而,由于这发生在多线程环境中,条目可能会在迭代过程中被删除 and/or 修改。发生这种情况时,迭代器上的 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上的方法是否是正确的选择?
是的,您应该使用两个参数 remove
方法。虽然在迭代期间直接改变集合对于大多数 java 集合来说通常是一件坏事,但 ConcurrentHashMap 允许这样做。