黑马程序员技术交流社区

标题: 并发异常为啥会这样呢 集合的 [打印本页]

作者: lindegen    时间: 2014-6-21 18:08
标题: 并发异常为啥会这样呢 集合的
本帖最后由 lindegen 于 2014-6-23 17:47 编辑

刚刚写了个迭代器,出现一个异常不是很明白为啥会这样子 大家给我说说
class Demo{
public static void main(String[] args){
List<String> al = new ArrayList<String>();
//创建一个迭代器,这一句放在这里就会出现[backcolor=rgba(255, 255, 255, 0.8)]ConcurrentModificationException异常
Iterator li = al.iterator();
al.add("abc");
al.add("bcd");
al.add("def");
//放在这里就能顺利打印出来
//Iterator li = al.iterator();
//遍历迭代器
while(li.hasNext()){
String str = li.next();
System.out.println(str);
}
}}



作者: 黄宝宝    时间: 2014-6-21 18:33
出现调用不确定性,简单说就是,你得到一个迭代器后,又向集合中添加元素!
作者: lindegen    时间: 2014-6-21 18:36
黄宝宝 发表于 2014-6-21 18:33
出现调用不确定性,简单说就是,你得到一个迭代器后,又向集合中添加元素! ...

那为虾米先添加元素,后获得迭代器就可以呢,难道说先获得迭代器会导致添加元素的不确定性? 具体是什么原因呢 小帅哥
作者: lindegen    时间: 2014-6-21 18:38
是不是列表里面没有内容获取迭代器就会出错呢?
作者: lindegen    时间: 2014-6-21 18:45
明白了,集合引用添加元素和迭代器同时操作元素会出现这个异常。先添加再获得迭代器就不会出现啦,也可以用ListIterator的add方法添加
作者: 黄宝宝    时间: 2014-6-21 18:52
lindegen 发表于 2014-6-21 18:36
那为虾米先添加元素,后获得迭代器就可以呢,难道说先获得迭代器会导致添加元素的不确定性? 具体是什么 ...

Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

  所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。
(注:网上copy,非原创),




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2