一.collection集合
1.collection集合存在iterator迭代器,作为替代方案出现了增强for
2.list集合中出现了listiterator,listiterator中增加了add()方法,加上iterator之前的remove()方法,可以解决并发修改异常
3.set集合中不存在普通for,因为无序;
注意:并发修改异常出现的原理是,遍历时操作集合,导致集合不一致;
例如:Arrallist是一个集合,若用iterator或者listiterator遍历时,相当于操作了Arrallist的复制版,当要在遍历删除时,应该用iterator或者listiterator中的remove()方法。
而不能用Arrallist中的方法。
代码:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
会出现异常情况:
1.
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {
if(iterator.next().equals(2)) {
list.add(10);
}
}
2.
ListIterator<Integer> listIterator = list.listIterator();
while (listIterator.hasNext()) {
if (listIterator.next().equals(2)) {
list
.add(10);
}
}
3.for(int temp : list) {
if(temp == 2) {
list.add(10);
}
}
注意:以上均是运用不同对象(list)操作了集合导致异常,
解决方案:
1、增强for无法解决,iterator只有在遍历的同时删除才可解决并发修改异常(用iterator的remove()方法),在遍历的同时添加时,iterator没有添加方法;
listiterator 遍历的同时删除和增加元素都可以,因为listiterator 中有remove()和add()方法;
2.用普通for; 注意 普通for,只是针对list集合(有序集合)出现的,存在get()方法;而set集合是唯一,无序,没有get()方法,不能用普通for。
3.倒序遍历;
不会出现异常情况:
1.
int length = list.size();
for (int i = 0; i < length; i++) {
if (list.get(i).equals(2)) {
list.add(10);
}
}
2.
ListIterator<Integer> listIterator = list.listIterator();
while (listIterator.hasNext()) {
if (listIterator.next().equals(2)) {
listIterator.add(10);
}
}
注意:若在普通for删除元素时,不要忘记 i--,并且多线程中也许要用普通for解决;
用listiterator 或者iterator仍然报并发修改异常.
例如:.
for
(
int
i =
0
; i < list.size()); i++) {
String value = list.get(i);
System. out.println(
"List Value:"
+ value);
if
(value.equals(
"3"
)) {
l
ist.remove(value);
// ok
i--;
// 因为位置发生改变,所以必须修改i的位置
}
}
二.map集合以下为转载 http://doublekj.blog.163.com/blog/static/146818474201251510248918/?COLLCC=1505412599&COLLCC=1387972087&COLLCC=1488635383&COLLCC=1941620215&
调用HashMap的reomve方法时会出现 java.util.ConcurrentModificationException 。
解决方法就是先用Iterator的方法remove,然后再调用HashMap的remove方法。
即代码如下:Iterator<Integer> keys = gradeMap.keySet().iterator();while(keys.hasNext()) { Integer i = keys.next(); if(!gradesIds.contains(i)) { keys.remove(); gradeMap.remove(i);
}
}
我加入这段代码之后,还是会出现该异常,于是继续寻找原因,发现了这样两段话:
1.如果你的程序是高并发,并且你的map是经常修改的,千万不要用HashMap,会把这个线常卡死的,要用ConcurrentHashMap2.虽然HashTable和ConcurrentHashMap都是线程安全的,但是HashTable是同步容器,ConcurrentHashMap是并发容器,
采用了锁分离策略,在并发环境中,应多使用ConcurrentHashMap,因为它具有非常好的并发性能,可以多个线程同时读写。
而HashTable只能同时一个线程读写。 可以简单的把ConcurrentHashMap理解为多个HashMap组合,锁不是在ConcurrentHashMap上,
而是在某个HashMap上。注意:ConcurrentHashMap和HashMap的一个不同点就是ConcurrentHashMap里不能存放key和value为空的值。
于是将Hashmap改为ConcurrentHashMap OK