我正在学习CopyOnWriteArrayList类。
因此,如果系统具有高并发性,并且大多数线程的操作都是读操作而不是写操作,那么最好使用CopyOnWriteArrayList
。
发布于 2013-07-25 16:48:26
如本link所述
CopyOnWriteArrayList是在Java5concurrency API中引入的一个并发集合类,以及它在Java语言中流行的表亲ConcurrentHashMap
。
CopyOnWriteArrayList
实现了像ArrayList
,Vector
和LinkedList
一样的List接口,但它是一个线程安全的集合,它实现线程安全的方式与向量或其他线程安全的集合类略有不同。
作为名称建议CopyOnWriteArrayList使用每个变异操作创建底层ArrayList的副本,例如添加或设置。通常情况下,CopyOnWriteArrayList是非常昂贵的,因为它涉及每个写操作的昂贵的数组拷贝,但它非常有效,如果你有一个列表,其中迭代数量超过变异,例如,你主要需要迭代ArrayList,而不是太频繁地修改它。
CopyOnWriteArrayList的迭代器是故障安全的,即使在迭代开始后底层CopyOnWriteArrayList被修改,也不会抛出CopyOnWriteArrayList,因为迭代器是在ArrayList的单独副本上操作的。因此,在CopyOnWriteArrayList上进行的所有更新都不能用于迭代器。
要获得最新的版本,请执行类似list.iterator();
的新代码
也就是说,更新这个集合会大大降低性能。如果您尝试对一个集合进行排序,您将看到该列表抛出了一个UnsupportedOperationException
(该CopyOnWriteArrayList
调用集合上的集合N次)。您应该仅在执行90+%读取以上操作时才使用此读取。
发布于 2013-07-25 16:54:50
复制新数组的目的是什么?
复制底层数组可以保证数据结构的任何迭代都是安全的,因为迭代发生在数据的本质上不变的“快照”上。
是否由其他线程读取数组?
说大也大吧。更具体地说,它是让每个线程能够安全地迭代数组,而不用担心ConcurrentModificationException
或其他未知/未定义的行为。
因此,如果系统是高并发的,并且大多数线程的操作都是读操作,而不是写操作,那么最好使用CopyOnWriteArrayList。我说的对吗?
不是的。只有当大多数线程的操作都是列表上的迭代时。如果大多数活动都是基于随机访问的读取,则ReadWriteLock
可能更好。
来自CopyOnWriteArrayList
的javadoc
这通常成本太高,但当遍历操作的数量远远超过突变时,这可能比其他方法更有效,并且当您不能或不想同步遍历,但需要排除并发线程之间的干扰时,此方法很有用。
https://stackoverflow.com/questions/17853112
复制相似问题