在Java中选择最佳的并发列表


98

我的线程池具有固定数量的线程。这些线程需要频繁地从共享列表中写入读取

那么,java.util.concurrent在这种情况下,包中的哪种数据结构(最好是一个列表,必须没有监视器)是最好的?


5
这取决于您要对集合进行什么操作。请参阅我的博客文章(尽管有关.Net,但是概念是相同的)。您不太可能使用编写正确的线程安全代码List
SLaks

1
现在,我正在使用CopyOnWriteArrayList,但仍会偶尔抛出ConcurrentModificationException异常。
象嘉道

2
请提供有关您对该系列所做的更多信息,以便人们可以更好地回答,否则仅是猜测。
mattsh 2011年

2
ConcurrentModificationException可能不是来自一个同步的问题; 例如,它还会在集合上的for循环中出现,您尝试从集合中删除元素。
2011年

1
我知道它不是包装的一部分,但是有人尝试过Vector吗?
WesternGun

Answers:


96

最好是 List

List实施java.util.concurrent的CopyOnWriteArrayList。正如Travis Webb所提到的,还有一个同步列表选项。

就是说,您确定要成为一个List吗?并发Queues和Maps 有更多选择(您可以SetMaps生成s),对于要使用共享数据结构执行的许多类型的操作,这些结构往往最有意义。

对于队列,您有很多选择,最合适的选择取决于您使用它的方式:


14
CopyOnWriteArrayList缺点是写操作非常昂贵(但读操作便宜)。如果要进行大量写操作,则最好使用同步列表或队列。
彼得·劳瑞

67

可以使任何Java集合都是线程安全的,如下所示:

List newList = Collections.synchronizedList(oldList);

或创建一个全新的线程安全列表:

List newList = Collections.synchronizedList(new ArrayList());

http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)


7
因此,在java.util.concurrent中找不到列表实现 -嗯,ConcurrentHashMap即使有Collections.synchronizedMap方法,也有一个。
aioobe

7
阅读上的Javadocs ConcurrentHashMap。同步实现的细节不同。使用中的synchronized方法Collections基本上只是将类包装在Java监视器中。ConcurrentHashMap使用更巧妙的并发功能。
Travis Webb

1
是的 尽管如此,它仍然使您的最后一句话无效。
aioobe

1
如果使用监视器,则该程序的性能确实很差:-(
象嘉道

5
仅添加,在newList上进行迭代不是线程安全的。!!
bluelurker


6

您可能想看看Doug Lea根据Paul Martin的“实用的无锁双链表”编写的ConcurrentDoublyLinkedList。它没有实现java.util.List接口,但是提供了您将在List中使用的大多数方法。

根据javadoc:

Deque(双端队列)的并发链接列表实现。并发插入,删除和访问操作可在多个线程之间安全地执行。迭代器是 弱一致性的,返回元素反映了创建迭代器时或创建迭代器后的双端队列状态。它们不会引发ConcurrentModificationException,并且可以与其他操作并发进行。


5

ConcurrentLinkedQueue使用无锁队列(基于较新的CAS指令)。


7
...未实现该List接口。
aioobe

1
eSniff,您将如何List.set(int index, Object element)使用ConcurrentLinkedQueue 实施?
John Vint的

4
大多数List特定于-的方法要么无法使用Queue(例如,在特定索引处添加/设置)无法实现,要么可以被实施,但效率不高(从索引获取)。所以我认为您无法真正包装它。就是说,我认为关于a的建议Queue很好,因为OP并未真正解释他们为什么需要a List
ColinD

1
@ColinD就是我要的答案。有很多原因导致无法将CLQ包裹在列表中。尽管我同意,但不能排除Queue接口。
John Vint

1
Wor️值得指出:“请注意,与大多数集合不同,size方法不是恒定时间操作。由于这些队列的异步性质,确定当前元素数需要遍历元素。”
Behrang Saeedzadeh,

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.