2

快速失败的迭代器迭代集合。如果集合在迭代时被修改,我们会得到异常。相反适用于故障安全,其中迭代发生在一个集合上,而写操作发生在它的副本上,因此这就是故障安全的工作方式(fe CopyOnWriteArrayList)。

有人可以解释一下 ConcurrentSkipListSet 如何具有故障安全功能吗?修改集合时没有副本(就像 CopyOnWrite 类一样),那么它是怎么发生的呢?我阅读是因为它的迭代器是弱一致的。我阅读了文档,我仍然不明白。(但我确实知道并发中的代码可见性或发生之前的关系是什么)。

有没有人有逻辑和易于记忆的解释,因为我是初学者?

//例子:

 ConcurrentSkipListSet<Integer> set = new ConcurrentSkipListSet<>();
      set.add(1);
      set.add(2);
      set.add(3);
      set.add(4);

      Iterator<Integer> iterator = set.iterator();
      while (iterator.hasNext()){
          System.out.println(iterator.next());
          set.remove(4);
      }

OUTPUT:
1
2
3

我期待在这里抛出 ConcurrentException ..请帮助:(

4

1 回答 1

2

“弱一致”术语在java.util.concurrent 包描述中定义:

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

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

在这种情况下ConcurrentSkipListSet,迭代器没有“快速失败”属性,而是反映了4已从集合中删除的修改。

在内部,ConcurrentSkipListSet是用 实现的ConcurrentSkipListMap,它的迭代器是通过跟踪接下来应该遍历哪个跳过列表节点来实现的。这自然会为您提供“弱一致”属性:如果下一项被删除,迭代器仍将返回它。如果下一个之后的项目被删除,迭代器将反映这些更改。

于 2020-08-22T11:40:53.020 回答