【问题标题】:Fail Safe Iterator giving unpredictable outputFail Safe Iterator 提供不可预测的输出
【发布时间】:2017-05-17 23:44:35
【问题描述】:

我有一个使用ConcurrentHashMap 的故障安全迭代器示例(参见下面的代码),其中两个条目在迭代时添加到映射中。

当其中一个值出现在输出中时,另一个值不会出现在输出中。

由于故障安全适用于地图副本而不是原始地图,因此迭代器是否应该在迭代时打印添加到地图的值?

public static void main(String[] args) {
    ConcurrentHashMap<String, Integer> mp = new ConcurrentHashMap<String, Integer>();  

    mp.put("one",1);
    mp.put("two",2);

    Iterator<String> itr=mp.keySet().iterator();

    while (itr.hasNext()) {
        String key=(String)itr.next();
        System.out.println(mp.get(key));
        mp.put("three",3);
        mp.put("FIVE",5);
        System.out.println(mp);
    } 
}   

【问题讨论】:

    标签: iterator concurrenthashmap


    【解决方案1】:

    keySet 迭代器不是故障安全的
    您看到的行为与已发布的合同一致。


    javadoc for ConcurrentHashMap#keySet() 说:

    视图的迭代器和拆分器是一致的。

    访问包级javadoc of the java.util.concurrent package 说:

    大多数并发集合实现(包括大多数队列) 也不同于通常的java.util 约定,因为它们的 迭代器和拆分器提供弱一致,而不是 快速失败遍历

    它们可能与其他操作同时进行
    他们永远不会扔ConcurrentModificationException
    它们保证遍历元素,因为它们在构造时就存在一次,并且可能(但不保证)反映构造后的任何修改

    (强调我的)

    【讨论】:

    • 在为 ConcurrentHashMap 使用迭代器时,迭代器是作用于地图的副本还是地图本身?
    猜你喜欢
    • 2020-02-18
    • 2015-07-02
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多