考试源码网站wordpress,网站推广怎么推广,上海网站商城建设公司,wordpress 淘宝客当您查看最受欢迎的Java面试问题时#xff0c;可能会遇到有关快速故障和故障安全迭代器的问题#xff1a; 故障快速迭代器和故障安全迭代器之间有什么区别#xff1f; 简化的答案是#xff1a; 如果在迭代过程中修改了集合#xff0c;则快速失败迭代器将引发ConcurrentM… 当您查看最受欢迎的Java面试问题时可能会遇到有关快速故障和故障安全迭代器的问题 故障快速迭代器和故障安全迭代器之间有什么区别 简化的答案是 如果在迭代过程中修改了集合则快速失败迭代器将引发ConcurrentModificationException 但不会失败保护。 尽管这完全有道理但不清楚访调员的故障安全含义。 对于迭代器Java规范未定义此术语。 但是有四种同时进行修改的策略。 并发修改 首先让我们定义什么是并发修改。 例如当我们有一个来自集合的活动迭代器并且对该集合进行了一些更改但它们不是来自我们的迭代器时会发生并发修改。 最明显的例子是当我们有多个线程时–一个线程正在迭代第二个线程在同一集合中添加或删除元素。 但是当我们在单线程环境中工作时我们也可以获取ConcurrentModificationException ListString cities new ArrayList();
cities.add(“Warsaw”);
cities.add(“Prague”);
cities.add(“Budapest”);IteratorString cityIterator cities.iterator();
cityIterator.next();
cities.remove(1);
cityIterator.next(); // throws ConcurrentModificationException不及格 上面的代码段是快速失败迭代器的示例。 如您所见一旦我们尝试从迭代器中获取第二个元素就会引发ConcurrentModificationException 。 迭代器如何知道创建集合后是否对其进行了修改 您可能在集合中有一个时间戳例如lastModified 。 创建迭代器时需要复制此字段并将其存储在迭代器对象中。 然后无论何时调用next()方法 lastModified需要将集合中的lastModified与迭代器中的副本进行比较。 例如可以在ArrayList实现中找到非常相似的方法。 有一个modCount实例变量其中包含对列表进行的修改次数 final void checkForComodification() {if (modCount ! expectedModCount)throw new ConcurrentModificationException();
} 值得一提的是快速失败迭代器是在尽力而为的基础上工作的-无法保证如果存在并发修改则会抛出ConcurrentModificationException 因此我们不应该依赖该行为-而是应将其用于检测错误。 大多数非并行集合都提供快速失败的迭代器。 弱一致性 java.util.concurrent包中的大多数并发集合例如ConcurrentHashMap和most Queues 都提供了弱一致性的迭代器。 文档中对它的含义进行了很好的解释 他们可能会与其他操作同时进行 他们永远不会抛出ConcurrentModificationException 它们被保证可以遍历在构造时已经存在的元素一次并且可以但不保证反映出构造后的任何修改。 快照 在此策略中迭代器从创建迭代器的那一刻起即与集合的状态相关联-我们的集合快照。 对初始集合所做的任何更改都会创建基础数据结构的新版本。 当然我们的快照是不变的因此它不反映在创建迭代器之后对集合所做的任何更改。 这是一种古老的好的写时复制COW技术。 它完全解决了并发修改问题因此不会引发ConcurrentModificationException 。 此外迭代器不支持元素更改操作。 写入时复制集合通常使用起来过于昂贵但是如果突变发生的次数显着减少遍历次数较少尝试一下可能是个好主意。 示例为CopyOnWriteArrayList和CopyOnWriteArraySet 。 未定义 未定义的行为可以在传统集合中找到例如Vector和Hashtables 。 它们都具有具有快速失败行为的标准迭代器但是它们还公开了Enumeration接口的实现该接口在定义并发修改时不定义行为。 您可能会看到某些项目被重复或跳过甚至出现一些奇怪的异常。 最好不要玩这个野兽 翻译自: https://www.javacodegeeks.com/2017/11/tale-two-iterators.html