两个迭代器的故事

当您查看最受欢迎的Java面试问题时,可能会遇到有关快速故障和故障安全迭代器的问题:

故障快速迭代器和故障安全迭代器之间有什么区别?

简化的答案是:

如果在迭代过程中修改了集合,则快速失败迭代器将引发ConcurrentModificationException ,但不会失败保护。

尽管这完全有道理,但不清楚访调员的故障安全含义。 对于迭代器,Java规范未定义此术语。 但是,有四种同时进行修改的策略。

并发修改

首先,让我们定义什么是并发修改。 例如,当我们有一个来自集合的活动迭代器并且对该集合进行了一些更改,但它们不是来自我们的迭代器时,会发生并发修改。 最明显的例子是当我们有多个线程时–一个线程正在迭代,第二个线程在同一集合中添加或删除元素。 但是,当我们在单线程环境中工作时,我们也可以获取ConcurrentModificationException

List<String> cities = new ArrayList<>();
cities.add(“Warsaw”);
cities.add(“Prague”);
cities.add(“Budapest”);Iterator<String> 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 。 此外,迭代器不支持元素更改操作。 写入时复制集合通常使用起来过于昂贵,但是如果突变发生的次数显着减少(遍历次数较少),尝试一下可能是个好主意。 示例为CopyOnWriteArrayListCopyOnWriteArraySet

未定义

未定义的行为可以在传统集合中找到,例如VectorHashtables 。 它们都具有具有快速失败行为的标准迭代器,但是它们还公开了Enumeration接口的实现,该接口在定义并发修改时不定义行为。 您可能会看到某些项目被重复或跳过,甚至出现一些奇怪的异常。 最好不要玩这个野兽!

翻译自: https://www.javacodegeeks.com/2017/11/tale-two-iterators.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/348681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库系统内部体系结构与外部体系结构

数据库系统的内部和外部体系结构 (1)内部体系结构模式&#xff1a;概念视图&#xff0c;概念级数据库&#xff0c;整个数据库的实际存储的抽象。一个数据库只有一个模式。 外模式&#xff1a;子模式&#xff0c;用户模式&#xff0c;最外层&#xff0c;是模式的子集&#xff0c…

三个世界及其有关概念

三个世界及其有关概念 数据库管理的对象(数据)存在于现实世界中&#xff0c;即现实世界中的事物及其各种联系。从现实世界的事物到存储到计算机的数据库中的数据,要数经历现实世界、信息世界和计机世界三个不同的世界,经历两级抽象和转换完成。 认识抽象&#xff0c;概念模型 1…

将文件拆分为流

上周&#xff0c;我讨论了类Pattern新的&#xff08;since 1.8&#xff09;方法splitAsStream可以处理字符序列&#xff0c;仅从流中读取该字符序列&#xff0c;并且不进行模式匹配以创建所有可能的元素并返回它作为流。 这种行为是流的本质&#xff0c;它是支持高性能应用程序…

数据模型

数据模型 现实世界中的事物及其联系,经过两级抽象和转换后形成了计算机世界中的数据及其联系,而数据模型就是用来描述数据及其联系的。 数据库中存放数据的结构是由数据模型决定的,数据模型是数据库的框架&#xff0c;是数据库系统的核心和基础。 数据模型是描述数据、数据联系…

activemq优先级_ActiveMQ消息优先级:工作原理

activemq优先级在邮件列表中 &#xff0c;通常会围绕ActiveMQ的消息优先级支持不断提出一些问题&#xff0c;以及有关观察到的行为和“真正支持什么”的好问题&#xff1f; 我希望可以帮助您了解幕后情况以及可以支持的优先级。 详细信息可能会有些麻烦。 如果您对这些细节不感…

移动通信

通信: 信源和信宿间信息的传输和交换构成了通信。 2)分类通信&#xff1a;固定通信&#xff0c;移动通信移动通信通信双方至少有-方在移动中(或者临时停留在某一非预定的位置 上)进行信息传输和交换。 这包括移动体(车辆、船舶、飞机和行人)和移动体之间的通信&#xff0c;移动…

移动通信(2)

二 移动通信系统工作方式 1)通信系统传输方式: 传输方式&#xff1a;单向&#xff0c;双向&#xff08;单工&#xff0c;半双工&#xff0c;双工&#xff09; 注意移动通信系统中所定义的工作方式与通信原理中并不一致。 2)工作方式类别 (1)单工通信:通信双方电台仅能交替地进行…

Java 9概览

对于许多Java 9来说&#xff0c;它似乎是一个维护版本&#xff0c;它推动了不能在Java 8中实现的项目Jigsaw。但是&#xff0c;随着JDK中的新模块系统以及与之相关的许多内部更改&#xff0c;Java 9也带来了开发人员工具箱中一些很棒的新内容。 以下是重点内容&#xff1a; JS…

数据库(3)——关系

关系的形式化定义和概念 &#xff08;1&#xff09;关系上域的定义Domain1)域是一组具有相同数据类型的值的集合,又称为值域。(用D表示)2)域中所包含的值的个数称为域的基数(用m表示)。 在关系中用域表示属性的取值范围。 D1{李力,王平&#xff0c;刘伟} , m3 ; &#xff08;2&…

数据库(4)——候选码和主键

候选码或候选键&#xff08;Candidate Key&#xff09; 如果在一个关系中&#xff0c;存在一个或一组属性的值能唯一地标识该关系的一个元组&#xff0c;则这个属性或属性组称为该关系的候选码或候选键&#xff0c;一个关系可能存在多个候选码。 候选码性质&#xff1a;唯一性&…

adf开发_了解ADF Faces clientComponent属性

adf开发我相信大多数ADF开发人员都知道ADF Faces属性clientComponent 。 在本文中&#xff0c;我将展示该属性实际上如何影响组件渲染以及它如何改变其行为。 让我们开始考虑一个非常简单的示例&#xff1a; <af:inputText label"Label 1" id"it1" /&g…

通信原理

绪论 1&#xff09;信息&#xff0c;消息&#xff0c;信号通信&#xff1a;利用电&#xff08;或者光&#xff09;信号传输消息中所包含的信息。信息&#xff1a;消息的内涵。 消息&#xff1a;信息的物理表现形式。&#xff08;可分为两类连续消息语音&#xff0c;音乐&#x…

Picocli 2.0:事半功倍

介绍 Picocli是一个单文件命令行解析框架&#xff0c;它使您几乎不需要任何代码即可创建命令行应用程序。 使用Option或Parameters注释应用程序中的字段&#xff0c;picocli将分别使用命令行选项和位置参数填充这些字段。 例如&#xff1a; Command(name "Greet", …

通信原理—通信系统组成

通信系统的组成 1一般模型信源——>发送设备——>信道&#xff08;噪声源&#xff09;——>接收设备——>信宿 通信系统是指传递信息所需的一切设备和信道的总体。 信源 &#xff1a;把消息变化原始电信号&#xff08;基带信号&#xff09;&#xff0c;非电量转化为…

无线通信(补充)

长波通信 长波通信是波长为1 000&#xff5e;10 000m&#xff08;频率为30&#xff5e;300kHz&#xff09;的无线电通信。 主要用于军事上&#xff0c;如潜艇通信、地下通信及导航等。 在一定范围内&#xff0c;长波通信以地波传播为主&#xff0c;当通信距离大于地波的最大传播…

Java 20年

二十年前&#xff0c;在苏黎世的一间公寓里发生了两件事。 我的女儿迈出了第一步&#xff0c;一位年轻的博士后研究员&#xff08;她的父亲&#xff09;迈出了使用Java的第一步。 很难完全理解当时的Java。 在这些时代&#xff0c;TCL盛行&#xff0c;Java时代与冰箱和烤面包机…

数据库设计()

数据库设计1 数据库设计的任务数据库设计是指根据用户需求研制数据库结构和行为的过程。对于一个给定的应用环境&#xff0c;构造最优的数据库模式&#xff0c;建立数据库及其应用系统;有效地存储数据&#xff0c;满足用户的信息要求和处理要求。 2数据库设计的特点 结构源于行…

移动通信—无线波传播

无线波传播 发射天线或自然辐射源所辐射的无线电波,通过自然条件下的媒质到达接受天线的过程称为无线电波传播。无线电波与可见光、X射线与γ射线-.样同属于电磁波,它们都是以电场和磁场为其特征的- -种电场震动。电磁波的频谱范围很宽,从几赫到3X 1023Hz(波长从几十兆米到10-9…

使用Dropwizard度量标准监视和测量无功应用

在上一篇文章中&#xff0c;我们创建了一个简单的索引代码&#xff0c;该代码可以对ElasticSearch进行数千个并发请求。 监视系统性能的唯一方法是老式的日志记录语句&#xff1a; .window(Duration.ofSeconds(1)) .flatMap(Flux::count) .subscribe(winSize -> log.debug(…

移动通信-多径效应,多普勒效应,菲涅尔区,阴影效应,快衰落,慢衰落

多径效应 信号从发射端到接收端常有许多时延不同、损耗各异的传输路径&#xff0c;可以是直射、反射或是绕射。无线电波的多径效应是指不同路径的相同信号在按收端叠加会增大或减小接收信号能量的现象。 时间色散 在无线通信中&#xff0c;无线电波从发射端到接收端会经过直射、…