import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
public class TestMap {
//public static HashMap m=new HashMap();
public static ConcurrentHashMap m=new ConcurrentHashMap();
public static ConcurrentSkipListSet s=new ConcurrentSkipListSet();
public static void main(String[] args){
testMap();
//testSet();
}
public static void testSet(){
new Thread(){
public void run(){
for(int i=0;i<100;i++){
s.add(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread(){
public void run(){
while(true){
System.out.println("cur:"+s.size());
for(Integer entry:s){
System.out.println(entry);
s.remove(entry);
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//entrys.clear(); 错误
//m.clear(); 错误
}
}
}.start();
}
public static void testMap(){
new Thread(){
public void run(){
for(int i=0;i<100;i++){
m.put(i , i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread(){
public void run(){
while(true){
Set entrys=m.entrySet();
System.out.println("cur:"+entrys.size());
for(Entry entry:entrys){
System.out.println(entry.getKey()+":"+entry.getValue());
m.remove(entry.getKey());
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//entrys.clear();
//m.clear();
}
}
}.start();
}
}
代码如上,如果多线程操作使用HashMap 或HashSet,一个线程写,一个线程读则会产生ConcurrentModificationException。
需要注意的是,运行结果你会发现使用并发ConcurrentHashMap与ConcurrentSkipListSet时,当前遍历的Set并不是size总是一样的,也就是如果另一个线程增加,size会动态增加,遍历次数会动态增加 。