【问题标题】:Is there an alternative to CopyOnWriteArrayList which can be sorted?是否有可以排序的 CopyOnWriteArrayList 的替代方法?
【发布时间】:2014-03-06 10:23:07
【问题描述】:

我在 GUI 中的“对象”上绘制了一组“效果”(渐变、纹理、文本等)。底层系统的性质意味着这个效果集合可以被多个线程访问。大多数操作都是读取,所以目前我使用的 CopyOnWriteArrayList 可以正常工作。

但是现在,每当我添加新效果或更改效果的绘制顺序时,我都需要根据效果的绘制顺序对效果集合进行排序。我还需要能够在正向和反向( iterator.next() 和 iterator.previous() )中遍历集合。

经过一些研究,我发现 CopyOnWriteArrayLists 不喜欢被排序:

Behaviour of CopyOnWriteArrayList

如果您尝试对 CopyOnWriteArrayList 进行排序,您将看到该列表引发 UsupportedOperationException(排序调用集合上的集合 N 次)。仅当您进行超过 90% 的读取时才应使用此读取。

我还发现了使用 ConcurrentSkipListSet 的建议,因为它可以处理并发和排序,但是查看 JavaDoc 我很担心:

请注意,与大多数集合不同,size 方法不是恒定时间操作。

我使用 & 相当依赖 size() 方法。

我可以在效果集合上实现一个手动同步系统作为标准 ArrayList,但这是一个非常大的重构&我宁愿用尽所有其他可能性,如果有人有任何想法吗?感谢您一直陪伴我。

【问题讨论】:

    标签: java sorting collections concurrency iteration


    【解决方案1】:

    可能最好的方法是在您对收藏进行排序时手动同步。你可以做类似(伪代码)的事情:

    synchronize { 
    
    convert copyonwritearrylist to normal list. 
    sort normallist. 
    convert normal list to copyonwritearraylist and replace the shared instance 
    
    }
    

    或者,您也可以只使用普通的 ArrayList 并使用 ReentrantReadWriteLock 推出自己的解决方案,如果您的读取次数多于写入次数,这应该可以正常工作。

    【讨论】:

    • 我将尝试融合您的第一个想法 - 使用第二个常规 ArrayList,我可以同步它存储对相同效果的引用,但唯一的目的是让它们以正确的顺序用于绘画。我可以对它进行排序并朝任一方向迭代。 - 感谢这个 (+1)
    猜你喜欢
    • 2023-03-27
    • 2013-10-18
    • 2010-12-25
    • 2021-11-06
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    相关资源
    最近更新 更多