【发布时间】:2012-12-11 23:34:20
【问题描述】:
我偶然发现了这个奇怪的错误。似乎Collections.sort() 不会以一种在迭代同一列表时能够检测并发修改的方式修改排序列表。示例代码:
List<Integer> my_list = new ArrayList<Integer>();
my_list.add(2);
my_list.add(1);
for (Integer num : my_list) {
/*
* print list
*/
StringBuilder sb = new StringBuilder();
for (Integer i : my_list)
sb.append(i).append(",");
System.out.println("List: " + sb.toString());
/*
* sort list
*/
System.out.println("CurrentElement: " + num);
Collections.sort(my_list);
}
输出
List: 2,1,
CurrentElement: 2
List: 1,2,
CurrentElement: 2
人们会期望ConcurrentModificationException,但它没有被提出,并且代码可以正常工作,尽管它不应该。
【问题讨论】:
-
你没有两个线程;没有并发(这真的该异常是要保护的)。即便如此...... 请注意,迭代器的快速失败行为不能得到保证,因为一般来说,在存在不同步的并发修改的情况下不可能做出任何硬保证。快速失败的迭代器会尽最大努力抛出 ConcurrentModificationException。因此,编写一个依赖于这个异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测错误。
-
如果您将元素添加到列表中(在同一个线程中),您确实会得到该异常。对我来说,为什么将元素添加到列表中是非法操作,但更改列表不是...
-
因为它没有在结构上修改
List,所以组成列表的节点都还在,甚至没有改变顺序。您的迭代器不受节点中包含的值更改的影响。简而言之,它真的不是为了保护你自己。
标签: java sorting collections