日期:2014-05-20  浏览次数:20769 次

线程安全集合类也有例外?
看了篇大大的文章,说,
线程安全类,如HashTable,Vector和通过Collections.synchronizedList()等方法获得的集合,
这些集合会当被迭代时,如果被其他线程访问,就会抛异常:ConcurrentModificationException

这是真的假的啊,毁三观啊啊啊啊啊

求真人指点一二。
------解决方案--------------------
doc说的线程安全很多都指的是相对线程安全
不可变类才是绝对线程安全的

看下面的例子:
Vector vector = new Vector();

thread 1:
for(int i = 0 ; i < 1000 ; i ++){
    vector.add("a");
    Thread.sleep(1000);
}



thread 2:
for(Object obj in vector){
    ...
}

thread 1每次add,vector内部都在发生变化(写)
而thread 2都是在没有加锁的情况下遍历(读取)vector的

所以抛出 ConcurrentModificationException 并发修改异常

想要避免这个异常的话,就必须避免并发修改,即:
Object lk = new Object();

thread 1:
lock(lk){
for(int i = 0 ; i < 1000 ; i ++){
    vector.add("a");
    Thread.sleep(1000);
}
}




thread 2:
lock(lk){
for(Object obj in vector){
    ...
}
}




------解决方案--------------------
HashTable,Vector和通过Collections.synchronizedList()等方法获得的集合对象本身是线程安全的,但没人跟你说其对应的Iterator也是线程安全的啊,已经是两个对象了