如果您知道访问模式不利,ConcurrentBag 仍然是支持对象池的正确选择吗?
Is a ConcurrentBag still the proper choice for backing an Object Pool if you know the access pattern will be unfavorable?
分析后,我发现通过使用对象池而不是构造对象池,我的应用程序中的特定对象将受益匪浅。此应用程序基于 producer/consumer 个多线程队列。
ConcurrentBag 集合基本上是一个对象池,作为应用程序对象池的后备存储似乎是完美的。如果我理解正确的话,ConcurrentBag 在概念上是这样工作的:
- 保留装袋对象的 ThreadLocal 集合。插入时加入这个集合,移除时从这个集合中移除。
- 如果本地集合中没有元素并且必须删除一个对象,请从另一个线程的本地集合中窃取一个。
问题是我已经知道应用程序将始终在线程 'A' 上请求对象,并且总是 return 在线程 'B' 上请求对象。因此,它将始终默认为窃取案例。
知道了这种访问模式,用框架提供的不同集合来支持对象池会更好吗?
对于您的用例,ConcurrentQueue 是更好的结构。正如您推测的那样,ConcurrentBag 应该只在您主要从同一个线程插入和拉出时才真正使用,ConcurrentQueue 没有线程亲和性。
大多数生产者消费者模型都有单独的线程写入和读取,这就是为什么 BlockingCollection<T>
使用 ConcurrentQueue<T>
作为其默认后备存储。
分析后,我发现通过使用对象池而不是构造对象池,我的应用程序中的特定对象将受益匪浅。此应用程序基于 producer/consumer 个多线程队列。
ConcurrentBag 集合基本上是一个对象池,作为应用程序对象池的后备存储似乎是完美的。如果我理解正确的话,ConcurrentBag 在概念上是这样工作的:
- 保留装袋对象的 ThreadLocal 集合。插入时加入这个集合,移除时从这个集合中移除。
- 如果本地集合中没有元素并且必须删除一个对象,请从另一个线程的本地集合中窃取一个。
问题是我已经知道应用程序将始终在线程 'A' 上请求对象,并且总是 return 在线程 'B' 上请求对象。因此,它将始终默认为窃取案例。
知道了这种访问模式,用框架提供的不同集合来支持对象池会更好吗?
对于您的用例,ConcurrentQueue 是更好的结构。正如您推测的那样,ConcurrentBag 应该只在您主要从同一个线程插入和拉出时才真正使用,ConcurrentQueue 没有线程亲和性。
大多数生产者消费者模型都有单独的线程写入和读取,这就是为什么 BlockingCollection<T>
使用 ConcurrentQueue<T>
作为其默认后备存储。