Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 故障安全迭代器_Java_Iterator_Concurrenthashmap - Fatal编程技术网

Java 故障安全迭代器

Java 故障安全迭代器,java,iterator,concurrenthashmap,Java,Iterator,Concurrenthashmap,我对故障安全迭代器的了解是,它创建原始数据结构的副本并对其进行迭代以允许并发修改。 我有一些困惑,比如: 修改是如何反映回原始数据结构的 如果我们有两个线程: 线程A:迭代器1删除一个元素(元素A) 线程B:迭代器2已开始迭代。如何向该迭代器传递原始DS已更改的信息 不能修改正在迭代的集合(concurent modification)。如果修改集合中的对象,它们也将在原始集合中修改 它将不会被传达。您正在迭代一个副本。如果您试图修改集合,请参见1 不能修改正在迭代的集合(concurent m

我对故障安全迭代器的了解是,它创建原始数据结构的副本并对其进行迭代以允许并发修改。 我有一些困惑,比如:

  • 修改是如何反映回原始数据结构的
  • 如果我们有两个线程: 线程A:迭代器1删除一个元素(元素A) 线程B:迭代器2已开始迭代。如何向该迭代器传递原始DS已更改的信息
  • 不能修改正在迭代的集合(concurent modification)。如果修改集合中的对象,它们也将在原始集合中修改

  • 它将不会被传达。您正在迭代一个副本。如果您试图修改集合,请参见1

  • 不能修改正在迭代的集合(concurent modification)。如果修改集合中的对象,它们也将在原始集合中修改

  • 它将不会被传达。您正在迭代一个副本。如果您试图修改集合,请参见1

  • 故障安全迭代器:

    故障安全迭代器复制内部数据结构(对象数组)并在复制的数据结构上进行迭代。对迭代器进行的任何结构修改都会影响复制的数据结构。因此,原始数据结构在结构上保持不变。因此,故障安全迭代器不会抛出ConcurrentModificationException

    与故障安全迭代器相关的两个问题是:

  • 维护复制的数据结构(即内存)的开销

  • 故障安全迭代器不保证正在读取的数据是原始数据结构中当前的数据

  • 根据Oracle文档,故障安全迭代器通常成本太高,但在遍历操作的数量远远超过变异时,可能比其他方法更有效,并且在您不能或不想同步遍历,但需要排除并发线程之间的干扰时,它非常有用。“快照”样式的迭代器方法使用对创建迭代器时数组状态的引用。此数组在迭代器的生存期内不会更改,因此不可能发生干扰,并且迭代器保证不会抛出ConcurrentModificationException。迭代器不会反映自迭代器创建以来对列表的添加、删除或更改。不支持对迭代器本身(remove()、set()和add())执行元素更改操作。这些方法引发不支持的操作异常。

    故障安全迭代器:

    故障安全迭代器复制内部数据结构(对象数组)并在复制的数据结构上进行迭代。对迭代器进行的任何结构修改都会影响复制的数据结构。因此,原始数据结构在结构上保持不变。因此,故障安全迭代器不会抛出ConcurrentModificationException

    与故障安全迭代器相关的两个问题是:

  • 维护复制的数据结构(即内存)的开销

  • 故障安全迭代器不保证正在读取的数据是原始数据结构中当前的数据

  • 根据Oracle文档,故障安全迭代器通常成本太高,但在遍历操作的数量远远超过变异时,可能比其他方法更有效,并且在您不能或不想同步遍历,但需要排除并发线程之间的干扰时,它非常有用。“快照”样式的迭代器方法使用对创建迭代器时数组状态的引用。此数组在迭代器的生存期内不会更改,因此不可能发生干扰,并且迭代器保证不会抛出ConcurrentModificationException。迭代器不会反映自迭代器创建以来对列表的添加、删除或更改。不支持对迭代器本身(remove()、set()和add())执行元素更改操作。这些方法引发UnsupportedOperationException。

    正如您已经知道的,“故障保护”迭代器在原始集合的克隆副本上工作。说明:

  • 修改是如何反映回原始数据结构的

    如果在对集合进行迭代时对其进行修改,则更改发生在原始副本上,而不是克隆副本(用于迭代)。因此,当前克隆副本的结构是完整的。见下文:

    public class FailSafeIteratorExample {
        public static void main(String[] args) {
            // Creating a ConcurrentHashMap
    
    
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
        // Adding elements to map
        map.put("abc", 1);
    
        // Here, we are working on clone copy.
        Iterator<String> it = map.keySet().iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            System.out.println(key + " : " + map.get(key));
            map.put("mno", 2); // This will not be reflected in the Iterator
        }
        System.out.println("\n\n");
    
        // Another clone copy just created with latest changes.
        // This will print the existing element with newly added element("mno")
        it = map.keySet().iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            System.out.println(key + " : " + map.get(key));
    
        }
    }}
    
    公共类故障保护迭代器示例{
    公共静态void main(字符串[]args){
    //创建ConcurrentHashMap
    
    ConcurrentHashMap=新的ConcurrentHashMap();
    //向地图添加元素
    地图放置(“abc”,1);
    //在这里,我们正在研究克隆拷贝。
    迭代器it=map.keySet().Iterator();
    while(it.hasNext()){
    String key=(String)it.next();
    System.out.println(key+”:“+map.get(key));
    put(“mno”,2);//这不会反映在迭代器中
    }
    System.out.println(“\n\n”);
    //刚刚用最新更改创建的另一个克隆副本。
    //这将使用新添加的元素(“mno”)打印现有元素
    it=map.keySet().iterator();
    while(it.hasNext()){
    String key=(String)it.next();
    System.out.println(key+”:“+map.get(key));
    }
    }}
    
  • 在第一次迭代集合时,我们插入了一个新条目“mno”,它不会反映在克隆副本中。但是当我们第二次迭代它时,另一个克隆副本是从原始集合中创建的,它有这个新添加的条目“mno”,因此,它被打印出来

  • 线程: 当单个线程在克隆副本上工作时修改集合时,无法进行通信。他们不知道其他线程对原始副本所做的更改