我正在学习CopyOnWriteArrayList课程。
因此,如果系统具有高并发性并且大多数线程的操作都在阅读而不是写入,那么最好使用CopyOnWriteArrayList
。
答案 0 :(得分:86)
正如link所述:
CopyOnWriteArrayList是Java 5 Concurrency API中引入的并发Collection类及其在Java中的流行表兄ConcurrentHashMap
。
CopyOnWriteArrayList
实现List接口,如ArrayList
,Vector
和LinkedList
,但它是一个线程安全的集合,它以与Vector略有不同的方式实现其线程安全性或其他线程安全的集合类。
顾名思义,CopyOnWriteArrayList创建底层副本 具有每个突变操作的ArrayList,例如添加或设置。一般 CopyOnWriteArrayList非常昂贵,因为它涉及昂贵 每次写入操作的数组副本,但如果你非常有效 有一个列表,其中迭代次数超过突变,例如你最需要的 迭代ArrayList并且不要经常修改它。
CopyOnWriteArrayList的迭代器是故障安全的,不会抛出 ConcurrentModificationException 即使是底层的 迭代开始后,CopyOnWriteArrayList被修改,因为 Iterator在ArrayList的单独副本上运行。因此全部 在迭代器上无法使用对CopyOnWriteArrayList进行的更新。
要获得最新版本,请执行list.iterator();
话虽如此,更新此系列将会扼杀性能。如果您尝试对CopyOnWriteArrayList
进行排序,则会看到列表抛出UnsupportedOperationException
(对集合调用的排序调用次数为N次)。只有在读取90%以上的读数时才应该使用此读数。
答案 1 :(得分:23)
应对新阵列的目的是什么?
复制基础数组可确保数据结构的任何迭代都是安全的,因为迭代是在数据的基本上不可变的“快照”上进行的。
其他线程是否可以读取数组?
排序。更具体地说,每个线程都能够安全地迭代数组,而不必担心ConcurrentModificationException
或其他未知/未定义的行为。
因此,如果系统是高并发性并且大多数线程的操作都在读取而不是写入,那么最好使用CopyOnWriteArrayList。我是对的吗?
没有。只有当大多数线程的动作都是列表上的迭代时。如果大多数活动是基于随机访问的读取,ReadWriteLock
可能会更好。
来自CopyOnWriteArrayList
这通常成本太高,但当遍历操作大大超过突变时,可能比替代方案更有效,并且当您不能或不想同步遍历时非常有用,但需要排除并发线程之间的干扰。