您的位置:首页 > 编程语言 > Java开发

java.util.ConcurrentModificationException 解决办法

2011-05-18 14:02 671 查看
今天在项目的中有一个需求,需要在一个Set类型的集合中删除满足条件的对象,这时想当然地想到直接调用Set的remove(Object o)方法将指定的对象删除即可,测试代码:

public class Test {

public static void main(String[] args) {

User user1 = new User();

user1.setId(1);

user1.setName("zhangsan");

User user2 = new User();

user2.setId(2);

user2.setName("lisi");

Set userSet = new HashSet();

userSet.add(user1);

userSet.add(user2);

for (Iterator it = userSet.iterator(); it.hasNext();) {

User user = (User) it.next();

if (user.getId() == 1) {

userSet.remove(user);

}

if (user.getId() == 2) {

user.setName("zhangsan");

}

}

for(Iterator it = userSet.iterator(); it.hasNext(); ) {

User user = (User) it.next();

System.out.println(user.getId() + "=>" + user.getName());

}

}

}

但运行程序的时候,却发现出错了:

Exception in thread "main" java.util.ConcurrentModificationException

at java.util.HashMap$HashIterator.nextEntry(Unknown Source)

at java.util.HashMap$KeyIterator.next(Unknown Source)

at test.Test.main(Test.java:23)

从API中可以看到List等Collection的实现并没有同步化,如果在多
线程应用程序中出现同时访问,而且出现修改操作的时候都要求外部操作同步化;调用Iterator操作获得的Iterator对象在多线程修改Set的时
候也自动失效,并抛出java.util.ConcurrentModificationException。这种实现机制是fail-fast,对外部
的修改并不能提供任何保证。

网上查找的关于Iterator的工作机制。Iterator是工作在一个独立的线程中,并且拥有一个
mutex锁,就是说Iterator在工作的时候,是不允许被迭代的对象被改变的。Iterator被创建的时候,建立了一个内存索引表(单链表),这
个索引表指向原来的对象,当原来的对象数量改变的时候,这个索引表的内容没有同步改变,所以当索引指针往下移动的时候,便找不到要迭代的对象,于是产生错
误。List、Set等是动态的,可变对象数量的数据结构,但是Iterator则是单向不可变,只能顺序读取,不能逆序操作的数据结构,当
Iterator指向的原始数据发生变化时,Iterator自己就迷失了方向。

如何才能满足需求呢,需要再定义一个List,用来保存需要删除的对象:

List delList = new ArrayList();

最后只需要调用集合的removeAll(Collection con)方法就可以了。

public class Test {

public static void main(String[] args) {

boolean flag = false;

User user1 = new User();

user1.setId(1);

user1.setName("shangsan");

User user2 = new User();

user2.setId(2);

user2.setName("lisi");

Set userSet = new HashSet();

userSet.add(user1);

userSet.add(user2);

List delList = new ArrayList();

for (Iterator it = userSet.iterator(); it.hasNext();) {

User user = (User) it.next();

if (user.getId() == 1) {

delList.add(user);

}

if (user.getId() == 2) {

user.setName("zhangsan");

}

}

userSet.removeAll(delList);

for(Iterator it = userSet.iterator(); it.hasNext(); ) {

User user = (User) it.next();

System.out.println(user.getId() + "=>" + user.getName());

}

}

}

转自:http://jackhlp.blog.163.com/blog/static/11796218200710221172542/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: