Webapp:安全地更新AppContext中的共享List / Map

时间:2010-06-18 14:59:37

标签: java list web-applications concurrency

我在WebAppContext中列出了地图和地图。
大多数情况下,这些仅由多个线程读取,但有时需要更新或添加一些数据 我想知道在没有引起ConcurrentModificationException的情况下,最好的方法是什么。

我认为使用CopyOnWriteArrayList我可以实现我想要的东西 - 我不必在每次读取操作上同步
- 我可以安全更新列表而其他线程正在读它。

这是最好的解决方案吗?地图怎么样?

2 个答案:

答案 0 :(得分:2)

使用CopyOnWriteArrayList时要小心。典型的集合(在很大范围内)是80%读取19%写入和1%删除。 CopyOnWriteArraylist在这些条件下表现不佳。 CopyOnWriteArrayList的最佳用途是读取时间约为90-95%。写得太多会降低性能(该类在调用compareTo时会抛出UnsupportedOperationException,因为它上面的Collections.sort很糟糕。)

基本上,如果您正在进行大量读取并且很少写入,则CopyOnWriteArrayList非常棒,但如果不是,则可以考虑使用Collections.synchronizedList。如果你想确保非阻塞读取,那么显然CopyOnWriteArrayList是合适的。

ConcurrentHashMap非常适合替换您拥有的任何地图实现(至少未排序)。它不会阻塞读取,并且只会阻止写入时的特定存储桶,所以速度非常快。

答案 1 :(得分:1)

CopyOnWriteArrayList应该适用于您想要的List。对于Map,您可能需要查看ConcurrentHashMap,除非您需要SortedMap,在这种情况下ConcurrentSkipListMap会更好。

我在ConcurrentHashMap中看到的唯一问题是它的迭代器仍然只能被一个线程一次访问,即使它们不会抛出ConcurrentModificationException