转载!
[JAVA技术集锦]Java技巧:拷贝枚举器以加强效率
东方细雨 发表于 2006-6-23 12:17:09 Java技巧:拷贝枚举器以加强效率
BUILDER.COM 2002-12-30
当一个代码段正对集合进行枚举而另一段代码试图修改这个集合时,就会发生常见的多线程问题。解决这一问题的方法是在处理前拷贝一份枚举变量。
在撰写多线程代码时,你遇到过多少次下面的提示:
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( );
}
}
枚举器的只读拷贝将用在同步状态上的时间减少到最小,因此可以增强全局的效率。
分享到:
- 2006-12-25 20:49
- 浏览 3593
- 评论(0)
- 论坛回复 / 浏览 (0 / 3574)
- 查看更多
相关推荐
5. **同步性问题**: - `ArrayList`自身不提供任何同步机制,因此在多线程环境下使用时,需要采取额外的同步措施,例如使用`Collections.synchronizedList`方法将其包装成同步集合。 #### 总结 `ArrayList`是一种...
- `ArrayList.Synchronized`:如果需要同步访问,则可以通过调用`ArrayList.Synchronized`方法获取一个新的同步化的`ArrayList`实例。例如: ```csharp ArrayList list = new ArrayList(); lock (list.SyncRoot...
而通过`ArrayList.Synchronized()`创建的线程安全实例,内部实现了锁机制,但在枚举操作时仍需注意同步问题。 5. **内存节省方法** 当ArrayList的Capacity大于实际需要时,可以通过`TrimToSize()`方法减少内存占用...
ArrayList不是线程安全的,这意味着在多线程环境下,对ArrayList的操作需要额外的同步措施,如使用`Collections.synchronizedList(ArrayList<T> list)`进行同步包装。 十、性能考量 1. 插入和删除元素:ArrayList在...
如果多个线程同时访问 `ArrayList`,则需要外部同步机制来确保线程安全。 **2. 数据增长策略** - **Vector**:默认情况下,当添加元素导致内部数组容量不足时,`Vector` 会将容量翻倍。这种增长策略有利于减少扩...
线程安全是指一个对象或方法在多线程环境下能够正确地处理共享数据,避免数据冲突和同步问题。在C#中,如果要在多线程中使用ArrayList,必须采取适当的同步措施,例如使用`lock`关键字、Monitor类或者`System....
- **线程安全**:ArrayList的实现不是线程安全的,意味着在多线程环境下,如果不进行外部同步控制,可能会出现数据不一致的情况。 2. **ArrayList的实现** - **底层结构**:ArrayList内部使用`Object[]`数组作为...
如果多个线程同时访问同一个ArrayList实例,并且其中至少有一个线程在结构上修改了列表(指的是改变列表的大小),那么必须在外部保持同步,以避免数据不一致的问题。这种情况下,可以通过诸如Collections....
`IsSynchronized` 属性指示当前的 ArrayList 实例是否支持线程同步,而 `ArrayList.Synchronized` 静态方法则会返回一个 ArrayList 的线程同步的封装。 如果使用非线程同步的实例,那么在多线程访问的时候,需要...
3. 线程安全性:ArrayList在Java中不是线程安全的,意味着在多线程环境下,不加同步控制地同时对ArrayList进行操作可能会导致数据不一致。如果需要线程安全,可以选择使用`java.util.concurrent....
- ArrayList 默认不是线程安全的,多线程环境下使用时需要手动同步,或者使用 `Collections.synchronizedList(ArrayList list)` 创建线程安全的 ArrayList。 6. **性能考虑** - ArrayList 的插入和删除操作在中间...
如果多个线程同时对同一个`ArrayList`实例进行结构修改(例如添加或删除元素),则需要手动同步这些操作,以避免数据不一致的问题。通常可以通过在访问`ArrayList`之前对`ArrayList`对象加锁来实现。 #### 总结 `...
### C# 中 ArrayList 的使用详解 #### 一、概述 在C#中,`ArrayList`是一种非常实用的数据结构,它可以被视为动态数组的...通过理解其构造函数、属性和常用方法,开发人员可以有效地利用`ArrayList`解决各种实际问题。
如果需要在多线程环境下使用,可以考虑使用`Collections.synchronizedList`方法对`ArrayList`进行同步,或者使用`CopyOnWriteArrayList`。 4. **效率比较**:相比于`LinkedList`,`ArrayList`在插入和删除元素时...
如果不进行同步控制,多线程环境下可能会出现数据不一致的问题。对于并发场景,可以使用CopyOnWriteArrayList(线程安全的ArrayList变体)和ConcurrentHashMap(线程安全的HashMap变体)。 总之,ArrayList和...
然而,这种安全性是以牺牲性能为代价的,因为每次操作都需要同步,导致了潜在的性能瓶颈。与ArrayList相比,Vector在插入和删除操作上的性能更差,尤其是在高并发场景下。 性能测试通常包括三个步骤:初始化、执行...
2. **线程安全**:ArrayList和LinkedList不是线程安全的,如果在多线程环境中使用,需要手动添加同步机制,或者选择Vector。 3. **内存消耗**:LinkedList比ArrayList和Vector占用更多的内存,因为它需要存储额外的...
例如,如果需要高并发且线程安全,可以选择 Vector 或者同步控制的 ArrayList;如果对性能要求较高且无需线程安全,ArrayList 是一个好选择;如果频繁进行插入和删除操作,LinkedList 更合适;如果需要线程安全的 ...
虽然ArrayList很方便,但它不是线程安全的,所以在多线程环境下需要额外的同步措施。此外,ArrayList的性能对于大型数据集可能不如更现代的集合类型,如List,后者提供了更强的类型安全性。 在提供的资源中,...
在使用 ArrayList 时,需要注意线程同步的问题,如果使用非线程同步的实例,那么在多线程访问的时候,需要自己手动调用 lock 来保持线程同步。同时,ArrayList.Synchronized 方法可以返回一个线程同步的 ArrayList ...