ConcurrentModificationException--同步容器支持iterator的任意修改吗?

1. 古老的HashTable

package com.cakes;
 
import java.util.Hashtable;
import java.util.Iterator;
 
public class ThreadSafeIteratorExample {
 
    public static void main(String[] args) {
	 
	Hashtable<String,String> myMap = new Hashtable<String,String>();
	myMap.put("1", "1");
	myMap.put("2", "2");
	myMap.put("3", "3");
	 
	Iterator<String> it1 = myMap.keySet().iterator();
	while(it1.hasNext()){
	    String key = it1.next();
	    System.out.println("Map Value:"+myMap.get(key));
	    if(key.equals("3")){
		myMap.remove("3");
		myMap.put("4", "4");
		myMap.put("5", "5");
	    }
	}
	 
	System.out.println("Map Size:"+myMap.size());
    }
 
}
/*
Map Value:3
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.Hashtable$Enumerator.next(Hashtable.java:1367)
	at com.cakes.ThreadSafeIteratorExample.main(ThreadSafeIteratorExample.java:17)
*/

不支持

2. 古老的Vector

import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
 
public class ThreadSafeIteratorExample {
 
    public static void main(String[] args) {
 
	Vector<String> myList = new Vector<String>();
	myList.add("1");
	myList.add("2");
	myList.add("3");
	myList.add("4");
	myList.add("5");
	 
	Iterator<String> it = myList.iterator();
	while(it.hasNext()){
	    String value = it.next();
	    System.out.println("List Value:"+value);
	    if(value.equals("3")){
		myList.remove("4");
		myList.add("6");
		myList.add("7");
	    }
	}
	System.out.println("List Size:"+myList.size());
	 
    }
 
}
/*
List Value:1
List Value:2
List Value:3
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.Vector$Itr.checkForComodification(Vector.java:1184)
	at java.util.Vector$Itr.next(Vector.java:1137)
	at com.cakes.ThreadSafeIteratorExample.main(ThreadSafeIteratorExample.java:22)
*/

不支持

3.  CopyOnWriteArrayList和ConcurrentHashMap

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
 
public class ThreadSafeIteratorExample {
 
    public static void main(String[] args) {
 
	List<String> myList = new CopyOnWriteArrayList<String>();
	myList.add("1");
	myList.add("2");
	myList.add("3");
	myList.add("4");
	myList.add("5");
	 
	Iterator<String> it = myList.iterator();
	while(it.hasNext()){
	    String value = it.next();
	    System.out.println("List Value:"+value);
	    if(value.equals("3")){
		myList.remove("4");
		myList.add("6");
		myList.add("7");
	    }
	}
	System.out.println("List Size:"+myList.size());
	 
	Map<String,String> myMap = new ConcurrentHashMap<String,String>();
	myMap.put("1", "1");
	myMap.put("2", "2");
	myMap.put("3", "3");
	 
	Iterator<String> it1 = myMap.keySet().iterator();
	while(it1.hasNext()){
	    String key = it1.next();
	    System.out.println("Map Value:"+myMap.get(key));
	    if(key.equals("1")){
		myMap.remove("3");
		myMap.put("4", "4");
		myMap.put("5", "5");
	    }
	}
	 
	System.out.println("Map Size:"+myMap.size());
    }
 
}

支持,不会抛出java.util.ConcurrentModificationException,不过请注意CopyOnWriteArrayList的iterator操作的是以前的copy之后的list

List Value:1
List Value:2
List Value:3
List Value:4
List Value:5
List Size:6
Map Value:1
Map Value:2
Map Value:4
Map Value:5
Map Size:4

 

4. Collections.synchronizedMap

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
 
public class ThreadSafeIteratorExample {
 
    public static void main(String[] args) {
 
	List<String> myList = Collections.synchronizedList(new ArrayList<String>());
	 
	myList.add("1");
	myList.add("2");
	myList.add("3");
	myList.add("4");
	myList.add("5");
	 
	Iterator<String> it = myList.iterator();
	while(it.hasNext()){
	    String value = it.next();
	    System.out.println("List Value:"+value);
	    if(value.equals("3")){
		myList.remove("4");
		myList.add("6");
		myList.add("7");
	    }
	}
	System.out.println("List Size:"+myList.size());
	 
	Map<String,String> myMap = Collections.synchronizedMap(new HashMap<String,String>());
	myMap.put("1", "1");
	myMap.put("2", "2");
	myMap.put("3", "3");
	 
	Iterator<String> it1 = myMap.keySet().iterator();
	while(it1.hasNext()){
	    String key = it1.next();
	    System.out.println("Map Value:"+myMap.get(key));
	    if(key.equals("1")){
		myMap.remove("3");
		myMap.put("4", "4");
		myMap.put("5", "5");
	    }
	}
	 
	System.out.println("Map Size:"+myMap.size());
    }
 
}

   

Map Value:1
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
	at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
	at com.cakes.ThreadSafeIteratorExample.main(ThreadSafeIteratorExample.java:22)

不支持

 

5.  ConcurrentSkipListMap

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
public class ThreadSafeIteratorExample {
 
    public static void main(String[] args) {

	 
	Map<String,String> myMap = new ConcurrentSkipListMap<String,String>();
	myMap.put("1", "1");
	myMap.put("2", "2");
	myMap.put("3", "3");
	 
	Iterator<String> it1 = myMap.keySet().iterator();
	while(it1.hasNext()){
	    String key = it1.next();
	    System.out.println("Map Value:"+myMap.get(key));
	    if(key.equals("1")){
		myMap.remove("3");
		myMap.put("4", "4");
		myMap.put("5", "5");
	    }
	}
	 
	System.out.println("Map Size:"+myMap.size());
    }
 
}

支持

-----

Vector和HashTable是线程安全的,既然是线程安全的,为什么不能在遍历iterator的时候另一个线程去修改Vector和HashTable? 考虑一下,我们在一个线程中获得了Vector的长度,然后另外一个线程删除了最后一个对象,那现在我即使get(Vector的长度-1)也会报错。

 

转载于:https://my.oschina.net/blacklands/blog/872436

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值