控制对 Java 集合的并发访问的最佳方式
我应该使用旧的同步矢量集合,具有同步访问权限的ArrayList还是Collections.synchronizedList或其他一些解决方案进行并发访问?
我在“相关问题”和搜索中都看不到我的问题(“使您的集合线程安全?不一样”)。
最近,我不得不对应用程序的GUI部分进行单元测试(基本上使用API来创建框架,添加对象等)。由于调用这些操作的速度比用户快得多,因此它显示了尝试访问尚未创建或删除的资源的方法的许多问题。
在EDT中发生的一个特殊问题来自在另一个线程中更改视图的链接列表(在其他问题中获得ConceptalModificationException)。不要问我为什么它是一个链接列表而不是一个简单的数组列表(甚至更少,因为我们里面通常有0或1视图......),所以我在我的问题中采用了更常见的ArrayList(因为它有一个年长的表亲)。
无论如何,我对并发问题不是很熟悉,我查找了一些信息,并想知道在旧的(可能是过时的)Vector(它通过设计上具有同步操作),ArrayList与周围关键部分(添加/删除/行走操作)或使用Collections.syncedList返回的列表(甚至不知道如何使用后者)之间进行选择。synchronized (myList) { }
我最终选择了第二个选项,因为另一个设计错误是公开对象(getViewList()方法...),而不是提供使用它的机制。
但是,其他方法的优缺点是什么?
[编辑]这里有很多好的建议,很难选择一个。我会选择更详细的,并提供链接/食物的想法... :-)我也喜欢达伦的那个。
总结一下:
- 正如我所怀疑的那样,Vector(以及它的邪恶孪生兄弟Hashtable)在很大程度上已经过时了,我看到人们说它的旧设计不如新集合好,除了即使在单线程环境中强制同步的缓慢之外。如果我们保留它,主要是因为较旧的库(以及Java API的一部分)仍在使用它。
- 与我想象的不同,Collections.synchronizedXxxx并不比Vector更现代(它们似乎是与Collections同时代的,即。Java 1.2!)实际上,并没有更好。很高兴知道。简而言之,我也应该避免它们。
- 毕竟,手动同步似乎是一个很好的解决方案。可能存在性能问题,但在我的情况下,它并不重要:对用户操作执行的操作,小型集合,不经常使用。
- java.util.concurrent package 值得记住,尤其是 CopyOnWrite 方法。
我希望我做对了... :-)