【问题标题】:Removing from a ConcurrentHashMap从 ConcurrentHashMap 中删除
【发布时间】: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


    【解决方案1】:

    是的,您应该使用两个参数remove 方法。虽然迭代期间的直接集合突变对于大多数 java 集合来说通常是一件坏事,但 ConcurrentHashMap 允许这样做。

    【讨论】:

    • 好的,谢谢。我知道这是一种可能性,只是不确定是否最优雅。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-23
    • 2013-02-16
    • 1970-01-01
    相关资源
    最近更新 更多