【问题标题】:Concurrent LinkedList vs ConcurrentLinkedQueue并发 LinkedList 与 ConcurrentLinkedQueue
【发布时间】:2016-11-16 08:00:51
【问题描述】:

我需要一个线程安全的并发列表,同时最适合迭代,并且应该返回确切的大小。 我想存储一个项目的拍卖出价。所以我希望能够

  1. 检索项目的确切出价数量
  2. 为项目添加出价
  3. 检索给定项目的所有出价。
  4. 删除项目的出价

我打算把它放在一个 ConcurrentHashMap<Item, LinkedList<ItemBid>> -- LinkedList 不是线程安全的,但返回精确的大小 ConcurrentHashMap<Item, ConcurrentLinkedQueue<ItemBid>> - concurrentlinked 队列是线程安全的,但不保证返回准确的大小

还有其他更好的集合可以解决以上 4 点并且是线程安全的。

【问题讨论】:

  • “精确尺寸”是什么意思?

标签: java multithreading concurrency


【解决方案1】:

可以说,在线程安全集合 映射中,您无法保证大小的“一致性”,这意味着读取和写入操作之间的“发生前”关系不会有利于您的期望用例,其中对大小的读取操作应返回反映上次写入操作的确切状态的值(NB:基于 cmets 改进 - 见下文)。

如果性能不是问题,您可以做的是使用以下成语 - 要么:

  • Collections.synchronizedMap(new HashMap<YourKeyType, YourValueType>());
  • Collections.synchronizedList(new ArrayList<YourType>());

然后您还需要显式同步这些对象。

这将以阻塞为代价确保操作顺序一致,并且您应该始终获得最后一个“正确”的大小。

【讨论】:

  • 线程安全集合确实建立了happens-before。这是“线程安全”含义的重要组成部分。我认为您要说的是线程安全不是可组合。也就是说,即使您的应用程序中的每个对象都是线程安全的,这也不会使您的 application 线程安全。仅仅因为一个集合是“线程安全的”并不能以任何方式保证一个应用程序线程放入集合中的东西就是其他应用程序线程期望在那里找到的东西。
  • 假设,这个系列将成为一个大型拍卖系统的一部分,每天有数百万个投标,所以性能是一个问题。使用装饰器来同步我的集合会影响性能。
  • @james_large 公平点,感谢您的澄清。我可能应该在我回家的时候编辑这个:)
  • @Kar 明白了,但是你怎么在任何时候都需要“精确”的尺寸?
【解决方案2】:

您可以使用LinkedBlockingQueue。它是阻塞的(与 CLQ 相对),但大小保持不变,不像 CLQ 那样被扫描。

【讨论】:

猜你喜欢
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-15
相关资源
最近更新 更多