CopyOnWriteArray或Vector

时间:2010-10-12 18:30:22

标签: java collections thread-safety

所有

边缘矢量类超过 ArrayList ,它是同步的,因此可以确保线程安全。但是,在CopyOnWriteArray和Vector之间,考虑到线程安全性和性能,应该首选什么。

2 个答案:

答案 0 :(得分:9)

总的来说,它取决于读写操作的频率和性质,以及数组的大小。

您需要在上下文中进行基准测试才能确定,但​​这里有一些基本原则:

  • 如果你只是去阅读 数组,然后甚至是ArrayList 线程安全(因为唯一的 非线程安全的修改 修改列表的那些)。于是 你会想要使用 非同步数据结构, 无论是ArrayList还是 可能会有CopyOnWriteArrayList 同样工作。
  • 如果读取更常见 与写作相比那么你会 倾向于喜欢CopyOnWriteArrayList, 因为数组复制开销是 仅在写入时发生。
  • 如果数组的大小是 小,然后制作成本 阵列副本也很小, 因此这将有利于 CopyOnWriteArrayList over Vector。

您可能还想考虑其他两个选项:

  • 使用ArrayList但将同步放在其他地方以确保线程安全。这实际上是我个人经常使用的方法 - 基本上我的想法是使用单独的更高级别的锁来同时保护所有相关的数据结构。这比Vector在每个操作上都有同步效率要高得多。
  • 考虑一个不可变的persistent data structure - 这些由于不变性而保证是线程安全的,不需要同步并且也从低开销中受益(即它们在不同实例之间共享大多数数据而不是制作完整的新副本)。像Clojure这样的语言使用这些语言来获得类似ArrayList的性能,同时还保证完整的线程安全。

答案 1 :(得分:8)

这取决于使用模式 - 如果您的读取数比写入数多,请使用CopyOnWriteArrayList,否则使用Vector

Vector为每个操作引入了一个小的同步延迟,当CopyOnWriteArrayList有更长的写入延迟(由于复制)但没有读取延迟时。

另一个考虑因素是迭代器的行为 - Vector在迭代时需要显式同步(因此写操作不能同时执行),CopyOnWriteArrayList没有。