java - 了解 CopyOnWriteArrayList 迭代器行为
问题描述
我正在学习CopyOnWriteArrayList
,下面的情况让我思考。
我的主要方法是这样的:
public static void main(String[] args) {
List<String> list = new CopyOnWriteArrayList<String>();
list.add("Init1");
list.add("Init2");
list.add("Init3");
list.add("Init4");
for(String str : list){
System.out.println(str);
list.add("PostInit");
}
}
在我读到的javadoc中:
内存一致性影响:与其他并发集合一样,线程中的操作在将对象放入 CopyOnWriteArrayList 之前发生在另一个线程中从 CopyOnWriteArrayList 访问或删除该元素之后的操作。
我期待一个无限循环,因为“在将对象放入 CopyOnWriteArrayList 之前的线程中的操作发生在访问或删除之后的操作之前”。
但我的控制台输出是:
Init1
Init2
Init3
Init4
我相信,我在这里缺乏一些了解。有人可以帮忙吗?
解决方案
从文档
“快照”风格的迭代器方法使用对创建迭代器时数组状态的引用。这个数组在迭代器的生命周期内永远不会改变,所以干扰是不可能的,并且迭代器保证不会抛出 ConcurrentModificationException。自创建迭代器以来,迭代器不会反映对列表的添加、删除或更改
for-each 循环正在使用迭代器,请参阅https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.14.2。
因此,for-each 循环将在 for 循环开始时打印列表中的元素,因为它是在那个时候创建迭代器的。
推荐阅读
- javascript - 如何在单击按钮时切换数据库中的值(YII2)
- jenkins - Jenkins 高级下拉参数
- highcharts - 提升面积图使其看起来像条形图
- javascript - d3 js onclicknode函数只返回id元素
- html - TinyMCE 使用“粘贴”插件将 alpha 列表转换为复制/粘贴时的编号列表
- typescript - 打字稿不能根据可选属性缩小联合
- javascript - 如何更新reactjs中的对象数组
- javascript - MS Edge api 错误“未定义浏览器”
- multithreading - 用户空间调度困境中的线程
- java - 从源代码自动生成 Java .class 文件的最安全方法,独立于构建环境