当一个代码段正对集合进行枚举而另一段代码试图修改这个集合时就会发生常见的多线程问题解决这一问题的方法是在处理前拷贝一份枚举变量
在撰写多线程代码时你遇到过多少次下面的提示
Exception in thread main javautilConcurrentModificationException
这个异常产生的原因有几个一是直接对集合调用删除操作而不是在枚举器上二是不同的线程试图对集合进行增删操作的时候
这个解决办法的第一步就是同步代码使得你在枚举的时候其它的线程不能增删记录但是如果每个枚举过程要进行复杂的计算或者是数据库访问的一部分的话这个同步就会导致可怕的后果为了减少负面影响可以拷贝一个只读的枚举器去掉同步然后采用下列代码所示的方法
private List list;
public void add(Object obj) {
synchronized(list) {
listadd(obj);
}
}
public void perform( ) {
Iterator iterator = null;
synchronized(list) {
iterator = new CopiedIterator(erator( ));
}
while(iteratorhasNext( )) {
// perform resource or cpu hungry work
}
}
重要的是记住CopiedIterator不是一个克隆只是一个只读的拷贝所以它并没有保持原有的全部功能最重要的是不能再调用CopiedIteratorremove方法了CopiedIteratorremove的实现如下
public class CopiedIterator implements Iterator {
private Iterator iterator = null;
public CopiedIterator(Iterator itr) {
LinkedList list = new LinkedList( );
while(itrhasNext( )) {
listadd(itrnext( ));
}
erator = erator( );
}
public boolean hasNext( ) {
return eratorhasNext( );
}
public void remove( ) {
throw new UnsupportedOperationException(This is a readonly iterator
);
}
public Object next( ) {
return eratornext( );
}
}
枚举器的只读拷贝将用在同步状态上的时间减少到最小因此可以增强全局的效率