JDK1.6集合框架bug 6260652解析
问题描述
JDK1.6版本的集合框架中存在一个bug,编号为6260652。该问题存在于java.util.HashMap
和java.util.HashSet
等集合类中的迭代器实现中。当在迭代过程中,同时修改集合中的元素,或更改元素hashCode值导致迭代器自动校验失败时,就会引发ConcurrentModificationException异常。
这个问题的根源是多线程在并发地处理集合数据,并且每个线程的操作不同步,导致数据状态突变,因而导致迭代器出现异常情况。
解决方案
为了解决这个问题,可以采用如下两种方式:
1.使用线程安全的集合类
在多线程情况下,不要使用非线程安全的集合类,最好使用线程安全的集合类,如java.util.Collections
中提供的synchronizedXXX方法(如,synchronizedMap
方法),或者使用java.util.concurrent.ConcurrentHashMap
,java.util.concurrent.CopyOnWriteArrayList
等线程安全的集合类。
2.避免在迭代过程中修改集合中元素数据
在迭代过程中,避免修改集合中元素数据,可以采用以下方式:
方案一、使用Iterator自身的方法,在迭代器遍历过程中进行集合的操作:
Map<Integer,String> map = new HashMap<>();
map.put(1,"Java");
map.put(2,"Python");
map.put(3,"Go");
Iterator<Integer> iterator = map.keySet().iterator();
while(iterator.hasNext()){
Integer key = iterator.next();
if(key == 2){
iterator.remove();//使用Iterator自身的方法,删除元素
}
System.out.println(map.get(key));
}
方案二、通过集合自身的方法,在集合遍历时进行元素的操作:
ConcurrentHashMap<Integer,String> map = new ConcurrentHashMap<>();
map.put(1,"Java");
map.put(2,"Python");
map.put(3,"Go");
for (Integer key : map.keySet()) {
if(key == 2){
map.remove(key);//使用集合自身的方法,删除元素
}
System.out.println(map.get(key));
}
示例
示例一:使用线程安全的集合
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class CollectionsDemo {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
map.put(1,"Java");
map.put(2,"Python");
map.put(3,"Go");
Map<Integer,String> syncMap = Collections.synchronizedMap(map);// 使用synchronizedMap方法,创建线程安全的Map实例。
Thread thread1 = new Thread(() -> {
for (Integer key : syncMap.keySet()) {
System.out.println(Thread.currentThread().getName()+" "+syncMap.get(key));
}
},"Thread-1");
Thread thread2 = new Thread(() -> {
syncMap.put(4,"C++");// 对线程安全的Map实例进行添加元素操作。
syncMap.remove(3);// 对线程安全的Map实例进行删除元素操作。
System.out.println(Thread.currentThread().getName()+" 完成添加和删除元素操作!");
},"Thread-2");
thread1.start();
thread2.start();
}
}
输出结果:
Thread-1 Java
Thread-1 Python
Thread-1 Go
Thread-2 完成添加和删除元素操作!
示例二:避免在迭代过程中修改元素数据
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class IteratorDemo {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
map.put(1,"Java");
map.put(2,"Python");
map.put(3,"Go");
Iterator<Integer> iterator = map.keySet().iterator();
while(iterator.hasNext()){
Integer key = iterator.next();
if(key == 2){
iterator.remove();//使用Iterator自身的方法,删除元素
}
System.out.println(map.get(key));
}
}
}
输出结果:
Java
Go
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JDK1.6集合框架bug 6260652解析 - Python技术站