【问题标题】:CopyOnWriteArrayList suitable only for iterations and not random access readsCopyOnWriteArrayList 仅适用于迭代而不适用于随机访问读取
【发布时间】:2019-12-20 04:05:58
【问题描述】:

我在this问题线程上看到了以下评论:

因为 CopyOnWriteArrayList 用于安全遍历。使用它的代价是为每次修改复制底层引用数组,并可能为迭代结构的陈旧版本的线程保留多个副本。 ReadWriteLock 将允许多个读取器,并且仍然允许偶尔的写入器执行必要的修改

我刚刚开始学习 CopyOnWriteArrayList,有人可以详细说明上述语句的含义吗?随机访问读取而不是迭代如何使 ReadWriteLock 成为更好的选择?

【问题讨论】:

  • CopyOnWriteArrayList 的迭代可能需要很长时间,因此根据您的用例,在迭代时需要进行一些修改。为了获得一致的结果,您将继续迭代开始迭代时存在的旧(陈旧)版本。随机访问只需要一点时间,所以不会留下旧版本。但是两次随机访问可能访问的不是同一个版本,它们之间总是会发生写操作。因此,例如,访问相邻索引可能不会为您提供相邻元素。
  • 评论已被删除。 (这可能意味着写它的人后悔写了它。)但这并不是说CopyOnWriteArrayList 不适合随机访问读取,或者ReadWriteLock 是一个更好的 选项。这只是说如果您不需要进行遍历,这是一种选择。 best 选项取决于列表大小、更新频率、预期读取性能以及您是否需要 CopyOnWriteArrayList 的特定保证迭代语义等因素。这不是您可以简化为简单的经验法则的事情。

标签: java collections copyonwritearraylist


【解决方案1】:

使用迭代器遍历CopyOnWriteArrayList时,调用iterator()会得到list的快照,以后的修改不会影响你的快照,所以从调用iterator的时候开始一直循环遍历数据副本.

对于随机访问循环,它将从当前新的列表副本中获取数据。并且如果发生一些修改,未来的随机访问会读取修改后的列表,可能会导致一些同步问题。因此,在这里,ReadWriteLock 将有助于使遍历线程安全。

【讨论】:

    猜你喜欢
    • 2021-06-25
    • 2013-05-26
    • 2012-04-20
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多