Java技巧:拷贝枚举器以加强效率

王朝java/jsp·作者佚名  2008-05-19
宽屏版  字体: |||超大  

当一个代码段正对集合进行枚举而另一段代码试图修改这个集合时,就会发生常见的多线程问题。解决这一问题的方法是在处理前拷贝一份枚举变量。

在撰写多线程代码时,你遇到过多少次下面的提示:

Exception in thread "main" java.util.ConcurrentModificationException

这个异常产生的原因有几个。一是直接对集合调用删除操作而不是在枚举器上。二是不同的线程试图对集合进行增删操作的时候。

这个解决办法的第一步就是同步代码,使得你在枚举的时候其它的线程不能增删记录。但是如果每个枚举过程要进行复杂的计算或者是数据库访问的一部分的话,这个同步就会导致可怕的后果。为了减少负面影响,可以拷贝一个只读的枚举器,去掉同步,然后采用下列代码所示的方法:

private List list;

public void add(Object obj) {

synchronized(list) {

list.add(obj);

}

}

public void perform( ) {

Iterator iterator = null;

synchronized(list) {

iterator = new CopiedIterator(list.iterator( ));

}

while(iterator.hasNext( )) {

// perform resource or cpu hungry work

}

}

重要的是记住,CopiedIterator不是一个克隆,只是一个只读的拷贝,所以它并没有保持原有的全部功能。最重要的是,不能再调用CopiedIterator.remove方法了。CopiedIterator.remove的实现如下:

public class CopiedIterator implements Iterator {

private Iterator iterator = null;

public CopiedIterator(Iterator itr) {

LinkedList list = new LinkedList( );

while(itr.hasNext( )) {

list.add(itr.next( ));

}

this.iterator = list.iterator( );

}

public boolean hasNext( ) {

return this.iterator.hasNext( );

}

public void remove( ) {

throw new UnsupportedOperationException("This is a read-only iterator.

");

}

public Object next( ) {

return this.iterator.next( );

}

}

枚举器的只读拷贝将用在同步状态上的时间减少到最小,因此可以增强全局的效率。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有