Phi*_*Lho 25 java collections concurrency
我应该使用旧的同步Vector集合,具有同步访问的ArrayList还是Collections.synchronizedList或其他一些并发访问的解决方案?
我没有在相关问题或我的搜索中看到我的问题(使你的收藏品线程安全吗?不一样).
最近,我不得不对应用程序的GUI部分进行单元测试(基本上使用API来创建框架,添加对象等).由于这些操作的调用速度比用户快得多,因此它显示了尝试访问尚未创建或已删除的资源的方法的许多问题.
在EDT中发生的一个特殊问题来自于在另一个线程中改变它时在一个链接的视图列表中行走(在其他问题中获得ConcurrentModificationException).不要问我为什么它是一个链表而不是一个简单的数组列表(更少,因为我们通常在0或1视图里面...),所以我在我的问题中采用了更常见的ArrayList(因为它有一个年长的堂兄).
无论如何,我不太熟悉并发问题,我查了一下信息,想知道在旧的(可能是过时的)Vector(它有设计的同步操作),ArrayList和synchronized (myList) { }周围关键部分(添加/删除)之间做出选择/ walk operations)或使用Collections.synchronizedList返回的列表(甚至不确定如何使用后者).
我最终选择了第二个选项,因为另一个设计错误是暴露对象(getViewList()方法...)而不是提供使用它的机制.
但其他方法的优缺点是什么?
[编辑]这里有很多好的建议,很难选择一个.我会选择更详细的,提供链接/食物的想法...... :-)我也喜欢Darron的.
总结一下:
我希望我做对了...... :-)
Ale*_*ler 23
Vector和Collections.synchronizedList()返回的List在道德上是一回事.我会认为Vector有效(但实际上)不推荐使用,而且总是更喜欢同步List.唯一的例外是需要Vector的旧API(特别是JDK中的API).
使用裸ArrayList并独立同步使您有机会更精确地调整同步(通过在互斥块中包含其他操作或通过在一个原子操作中组合对List的多个调用).不利的一面是,可以编写访问同步之外的裸ArrayList的代码,该代码被破坏.
您可能需要考虑的另一个选项是CopyOnWriteArrayList,它将为您提供线程安全,如Vector和synchronized ArrayList,以及不会抛出ConcurrentModificationException的迭代器,因为它们正在处理数据的非实时快照.
您可能会发现这些有关这些主题的最新博客有趣:
Dar*_*ron 13
我强烈推荐" Java Concurrency in Practice " 一书.
每个选择都有优点/缺点:
jcr*_*ey3 10
我想不出永远喜欢一个很好的理由Vector了ArrayList.a上的列表操作Vector是同步的,这意味着多个线程可以安全地更改它.就像你说的,ArrayList的操作可以使用同步Collections.synchronizedList.
请记住,即使使用同步列表,ConcurrentModificationExceptions如果在另一个线程修改集合时迭代该集合,您仍会遇到.因此,从外部协调该访问(第二个选项)非常重要.
用于避免迭代问题的一种常用技术是迭代集合的不可变副本.看到Collections.unmodifiableList
我会一直去java.util.concurrent(http://java.sun.com/javase/6/docs/api/java/util/concurrent/package-summary.html)包,看看是否有任何合适的系列.如果对列表进行少量更改但迭代次数较多,则java.util.concurrent.CopyOnWriteArrayList类很好.
我也不相信Vector和Collections.synchronizedList会阻止ConcurrentModificationException.
如果你没有找到合适的集合,那么你必须进行自己的同步,如果你不想在迭代时持有锁,你可能需要考虑制作副本并迭代副本.
| 归档时间: |
|
| 查看次数: |
29436 次 |
| 最近记录: |