Java多线程:将对象添加到列表/队列/集合的廉价操作

时间:2018-07-31 09:08:34

标签: java multithreading thread-safety add java.util.concurrent

因此,基本上,我需要一种将对象(我们称为Element)添加到List / Queue / Set或具有多个线程的类似对象的方法。由于我需要添加很多元素(不确定多少,但请相信我很多),因此该操作应该很便宜。无需删除它们。将每个元素添加到列表中也非常重要。

基本上我正在寻找这个

  • 线程安全
  • 便宜的添加功能
  • 不具有可比性/未排序
  • 每个元素都需要添加

在我看来,由于 CopyOnWriteArrayList 听起来很昂贵,所以我不认为这是一个选择。

不幸的是,我无法使Element具有可比性,因此 ConcurrentSkipListSet 不是一个选择。

Collections.synchronizedList()听起来也太昂贵了。

目前,我正在考虑使用 ConcurrentLinkedQueue 或只是像这样同步add方法:

private synchronized void add(Element elem){
    elements.add(elem);
}

2 个答案:

答案 0 :(得分:1)

通常,您应该坚持使用JDK库中的方法和类。它们往往已进行了相当优化,并且在将来的版本中将无法使用,这将导致您无需费力地更新代码。实际上,这是Joshua Bloch的Effective Java中的一项。

遵循该规则,由于您似乎并不真正在乎您真正获得的是哪种收藏夹(问题中的“ List / Queue / Set”),你为什么不做

Collection<YourData> synced = Collections.synchronizedCollection(new LinkedList<>());

LinkedList优化添加元素(与ArrayList相反,当容量用完时将复制基础数组),synchronizedCollection将进行synchronized包装(如果您查看代码,它的实现完全符合您的建议)。 synchronizedList也是如此。

答案 1 :(得分:0)

我认为您可以基于guava中的ConcurrentHashMultiset实现一个Collection。

ConcurrentHashMultiset是基于ConcurrentHashMap实施的,它做了很多事情以获得稳定的性能。