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)也会报错。