在Java中select最好的并发列表
我的线程池有固定数量的线程。 这些线程需要经常从共享列表中读写 。
那么,在这种情况下, java.util.concurrent
包中的哪个数据结构(最好是List,必须是无监视器的)呢?
最好是
List
java.util.concurrent
唯一的 List
实现是CopyOnWriteArrayList 。 Travis Webb也提到了同步列表的选项。
这就是说,你确定你需要它成为一个List
? 并发Queue
和Map
有更多的select(你可以使用Map
来Set
),而这些结构对于你想用共享数据结构进行处理的许多types往往是最有意义的。
对于队列,您有很多选项,哪一个最合适取决于您需要如何使用它:
- 的ConcurrentLinkedQueue
- ArrayBlockingQueue
- LinkedBlockingDeque
- 的LinkedBlockingQueue
- 的PriorityBlockingQueue
- 的SynchronousQueue
- DelayQueue
任何Java集合都可以像下面这样做成线程安全的:
List newList = Collections.synchronizedList(oldList);
或者创build一个全新的线程安全列表:
List newList = Collections.synchronizedList(new ArrayList());
如果列表的大小固定,那么你可以使用AtomicReferenceArray 。 这将允许您对插槽执行索引更新。 如果需要,你可以写一个列表视图。
ConcurrentLinkedQueue
使用一个无锁队列(基于较新的CAS指令 )。
你可能想看看Doug Lea基于Paul Martin的“实用无锁双链表”编写的ConcurrentDoublyLinkedList 。 它没有实现java.util.List接口,但提供了在List中使用的大多数方法。
根据javadoc:
Deque(双端队列)的并发链接列表实现。 并发插入,删除和访问操作在多个线程中安全地执行。 迭代器是弱一致的 ,在创build迭代器时或之后返回反映元素状态的元素。 他们不抛出ConcurrentModificationException,并可能与其他操作同时进行。
如果设置足够,则可以使用ConcurrentSkipListSet 。 (其实现基于实现跳过列表的 ConcurrentSkipListMap 。)
包含,添加和删除操作的预期平均时间成本为log(n); size方法不是一个常量操作。