为什么 ArrayList 在从多个线程修改时不会抛出 ConcurrentModificationException?

2023-12-03

ConcurrentModificationException :如果不允许进行对象的并发修改,则检测到并发修改的方法可能会引发此异常。

上面是 javadoc 中的 ConcurrentModificationException 定义。

所以我尝试测试下面的代码:

final List<String> tickets = new ArrayList<String>(100000);
for (int i = 0; i < 100000; i++) {
    tickets.add("ticket NO," + i);
}
for (int i = 0; i < 10; i++) {
    Thread salethread = new Thread() {
        public void run() {
            while (tickets.size() > 0) {
                tickets.remove(0);
                System.out.println(Thread.currentThread().getId()+"Remove 0");
            }
        }
    };
    salethread.start();
}

代码很简单。 10 个线程从 arraylist 对象中删除元素。 可以肯定的是,多个线程访问一个对象。但运行正常。没有抛出异常。 为什么?


我引用了很大一部分内容ArrayListJavadoc 为您带来好处。解释您所看到的行为的相关部分会突出显示。

请注意,此实现不是同步的。如果是多线程 同时访问 ArrayList 实例,并且至少其中之一 线程从结构上修改列表,必须同步 外在地。 (结构修改是任何添加或 删除一个或多个元素,或显式调整后备数组的大小; 仅仅设置元素的值不是结构性的 修改。)这通常是通过同步某些 自然封装列表的对象。如果不存在这样的对象, 列表应该使用 Collections.synchronizedList “包装” 方法。最好在创建时完成此操作,以防止意外 对列表的不同步访问:

列表列表 = Collections.synchronizedList(new ArrayList(...));

此类的 iterator 和 listIterator 方法返回的迭代器 快速失败:如果列表在结构上随时被修改 迭代器以任何方式创建,除了通过迭代器自己的 删除或添加方法时,迭代器将抛出 并发修改异常。因此,面对并发 修改后,迭代器会快速而干净地失败,而不是 在不确定的时间冒任意、非确定性行为的风险 将来。

请注意,无法保证迭代器的快速失败行为 因为一般来说,不可能做出任何硬性保证 存在不同步并发修改的情况。快速失败 迭代器尽力抛出 ConcurrentModificationException 基础。因此,编写依赖于 关于此异常的正确性:快速失败行为 迭代器应该仅用于检测错误。

如果从结构上修改列表,ArrayLists 通常会抛出并发修改异常通过迭代器访问它时(但即使这也不是绝对的保证)。请注意,在您的示例中,您直接从列表中删除元素,并且没有使用迭代器。

如果您感兴趣,您还可以浏览以下实现ArrayList.remove,以便更好地了解其工作原理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 ArrayList 在从多个线程修改时不会抛出 ConcurrentModificationException? 的相关文章

随机推荐

  • Excel vba xml解析性能

    我正在努力在 Excel 中获取一些输入数据 将其解析为 xml 并使用它来运行 SQL 存储过程 但我遇到了 xml 解析的性能问题 输入表看起来像这样 Dates Name1 Name2 Name3 NameX Date1 Date2
  • 获取子文件夹Azure数据工厂中的所有文件名

    我在数据湖中有一个以下文件夹结构 我想从 ParentFolder 目录的所有子文件夹中获取所有 csv 文件名 我的所有文件都是 csv 文件 是否有一种使用元数据活动的简单方法 父文件夹 gt 年 2020 文件夹 2020 10 20
  • 防止滑动 UIPageViewController 时出现白色间隙

    我以这种方式实现了 UIPageViewController GalleryViewController 是PageViewController的容器 PageViewController 是 uipageViewController 我将
  • 如何使用C#计算段落中某个单词的数量

    我正在尝试编写一个程序 用户向系统提供一个单词和一个段落 系统的工作是计算该单词出现的次数 如何计算 C 中该单词出现的次数 使用正则表达式字边界 anchor int wordCount Regex Matches text b Rege
  • Inno Setup 桌面快捷方式(链接),其中设置了“以管理员身份运行”高级属性

    我正在努力让 Inno setup 5 5 9u 创建一个带有图标并具有高级属性的桌面快捷方式 以管理员身份运行 set Issue 这个问题与以下问题有点不同 如何使用 Inno Setup 在文件上设置 以管理员身份运行 因为我想做的不
  • 匿名 JSON 对象集合的单元测试

    这个问题的灵感来自于此很好的例子 我有 ASP NET Core MVC 应用程序 我正在编写单元测试对于控制器 其中一种方法返回JsonResult具有匿名类型的集合 我可以找到集合中的每个元素 我还可以像这样断言每个元素中的值 Dict
  • Expand.grid 的非冗余版本

    The R功能expand grid返回所提供参数的元素之间的所有可能组合 例如 gt expand grid c aa ab cc c aa ab cc Var1 Var2 1 aa aa 2 ab aa 3 cc aa 4 aa ab
  • C# 打印屏幕活动窗口

    我目前正在尝试使用 Visual C 打印活动窗口的屏幕 我有这个代码 SaveFileDialog saveImageDialog new SaveFileDialog saveImageDialog Title Select outpu
  • 无法使用 Linux 文件系统在 docker for windows 中运行 mongoDb 容器

    我正在尝试在 Windows 中运行 mongo db 容器 并将卷映射到 Windows 文件夹 我遵循了巴巴克的回答this问题 该文件夹映射正确 但它创建了许多名为 WiredTiger wt 1 的文件 其中末尾的数字不断递增 我在
  • 没有 JSONP 的 JSON 跨站点

    我有一个本地硬件 我可以通过它的 IP 地址访问它来检索 json 数据 我正在创建一个基于 Web 的应用程序 但由于跨域问题 当应用程序在 Web 上运行时 它无法访问本地 json 数据 是否有合适的解决方案使 JSON 数据可供 W
  • 使用 DB Browser for SQLite 从一种日期格式转换为另一种日期格式

    我希望使用 SQL 将一种日期格式转换为另一种日期格式 我正在使用 SQLite 的数据库浏览器 日期存储在 TEXT 类型的列中 以下是当前格式的 2 个示例 2017 年 4 月 17 日 9 09 09 上午 10 4 2017 10
  • SQL 按*可能*为空的字段进行连接

    在我的 SQL CE 数据库中 我有三个表 customer list and customerlist 之间的联结表customer and list 因为它是多对多关系 我正在尝试运行一个查询 该查询将显示所有当前列表以及当前订阅该列表
  • Spring数据是否需要休眠

    我对Spring Data的实现有一个疑问 对Spring Data有基本的了解 我了解 JPA 和 Hibernate 及其工作原理 Hibernate 提供了JPA 的实现 我的问题是 我们可以单独使用 Spring 数据将数据保存在
  • 用于选择属于多个类别的帖子的 SQL 查询

    我正在编写一个类似于博客软件的网络应用程序 有如下三张表 Posts Table Post id Post Text Post Tags Table Post id Tag id Tags Table Tag id Tag name 我很难
  • ncursesw 函数未声明

    我需要使用支持 unicode 的 ncurses 因此我将以下行添加到我的 c 文件中 include
  • ASP.NET MVC Razor 部分和部分

    我对 ASP NET MVC 和 Razor 比较陌生 我们一直在现有代码的基础上进行修改和开发 因此 存在大量重复 呃 所以我开始查看部分页面并学习部分 我遵循了这些教程 但我仍然有点困惑 ASP NET MVC 3 使用 Razor 进
  • 无效的作者/提交者行 - 电子邮件前缺少空格

    我有一个git从克隆的存储库bzr存储库使用git remote bzr如下 git clone bzr repo new repo 经过数百次提交后 我执行了git fsck我收到以下错误bzr承诺 提交 41bf5 中的错误 作者 提交
  • Google 地图 api v3 上的反向地理编码

    我想知道是否有人可以帮助我 我使用下面所示的代码在 Google 地图上正确绘制从 MySQL 数据库检索到的标记
  • 如何为 MATLAB 矩阵的对角线赋值?

    假设我有一个 NxN 矩阵 A 一个由数字 1 N 的子集组成的索引向量 V 和一个值 K 我想这样做 for i V A i i K end 有没有一种方法可以在一个带有向量化的语句中做到这一点 e g A 某物 K 该声明A V V K
  • 为什么 ArrayList 在从多个线程修改时不会抛出 ConcurrentModificationException?

    ConcurrentModificationException 如果不允许进行对象的并发修改 则检测到并发修改的方法可能会引发此异常 上面是 javadoc 中的 ConcurrentModificationException 定义 所以我