概述
当我们运行如下代码时:会产生并发的修改异常java.util.ConcurrentModificationException,其原因是迭代集合的时间不能够对集合进行修改。
package andy.thread.test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionModifyExceptionTest {
public static void main(String[] args) {
Collection<User> users = new ArrayList<User>();
users.add(new User("张三", 28));
users.add(new User("李四", 25));
users.add(new User("王五", 31));
Iterator<User> itrUsers = users.iterator();
while (itrUsers.hasNext()) {
User user = (User) itrUsers.next();
if ("张三".equals(user.getName())) {
users.remove(user);
// itrUsers.remove();
} else {
System.out.println(user);
}
}
}
static class User {
private String name;
private Integer age;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
}
}
会抛出如下的异常:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at andy.thread.test.CollectionModifyExceptionTest.main(CollectionModifyExceptionTest.java:17)
但是当我们删除李四时却没有抛错误。
查看源码之后我们就可已清楚的了解,删除李四时,其迭代器中 boolean hasNext();返回为false,没有执行一下代码;而删除第一个和第五个时,会产生期望值和list的值不相等,就抛出异常。
private void checkForComodification() {
if (ArrayList.this.modCount != this.modCount)
throw new ConcurrentModificationException();
}
JDK1.5之后,给我们提供了CopyOnWriteArrayList
这种方法可能比其他替代方法更 有效。在不能或不想进行同步遍历,但又需要从并发线程中排除冲突时,它也很有用。“快照”风格的迭代器方法在创建迭代器时使用了对数组状态的引用。此数组在迭代器的生存期内不会更改,因此不可能发生冲突,并且迭代器保证不会抛出 ConcurrentModificationException。创建迭代器以后,迭代器就不会反映列表的添加、移除或者更改。在迭代器上进行的元素更改操作(remove、set 和 add)不受支持。这些方法将抛出 UnsupportedOperationException。
修改代码:
package andy.thread.test;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
public class CollectionModifyExceptionTest {
public static void main(String[] args) {
Collection<User> users = new CopyOnWriteArrayList<>();
users.add(new User("张三", 28));
users.add(new User("李四", 25));
users.add(new User("王五", 31));
Iterator<User> itrUsers = users.iterator();
while (itrUsers.hasNext()) {
User user = (User) itrUsers.next();
if ("张三".equals(user.getName())) {
users.remove(user);
// itrUsers.remove();
} else {
System.out.println(user);
}
}
}
static class User {
private String name;
private Integer age;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
}
}
就不会有问题。
最后
以上就是会撒娇指甲油为你收集整理的多线程之操作CopyOnWriteArrayList解决Iterator迭代器产生java.util.ConcurrentModificationException的全部内容,希望文章能够帮你解决多线程之操作CopyOnWriteArrayList解决Iterator迭代器产生java.util.ConcurrentModificationException所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复