我的线程池有固定数量的线程。这些线程需要经常从共享列表中获取 写作和 读。
那么,在这种情况下,java.util.concurrent包中的哪种数据结构(最好是 List,必须是无监视器的)是最好的呢?
java.util.concurrent
ConcurrentLinkedQueue 使用无锁队列(基于较新的 CAS 指令)。
ConcurrentLinkedQueue
任何 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)
最好是 List
List
java.util.concurrent中的 只有 List实现是 CopyOnWriteArrayList。
也就是说,你确定你需要 List吗?对于并发的 Queue和 Map有更多的选择(你可以从 Map中制作出 Set) ,这些结构对于你想用共享数据结构做的许多事情来说是最有意义的。
Queue
Map
Set
For queues, you have a huge number of options and which is most appropriate depends on how you need to use it:
你可能想看看 Doug Lea 根据 Paul Martin 的“一个实用的无锁双链表”写的 ConcurrentDoublyLinkedList。它不实现 java.util。列表接口,但提供在列表中使用的大多数方法。
根据 javadoc 的说法:
Deque 的并发链表实现 (双端队列)。同时插入,删除和访问 操作在多个线程间安全执行 弱一致的 ,返回反映 在迭代器创建之时或之后的某个点上的 deque 执行 not抛出 Concurrent 修改异常,并且可能 与其他操作同时进行。
如果列表的大小是固定的,那么可以使用 AtomicReferenceArray。这将允许您对插槽执行索引更新。如果需要,可以编写 List 视图。
If set is sufficient, ConcurrentSkipListSet might be used. (它的实现基于实现 跳过清单的 ConcurrentSkipListMap。)
对于包含、添加和删除操作,预期的平均时间开销为 log (n) ; size 方法不是常量时间操作。