现在,我有一个队列,有多个生产者和单个消费者。
消费者线程操作很慢。此外,使用者通过窥视操作从队列中获取元素,直到消耗操作完成,该元素无法从队列中删除。这是因为作为副操作的生产者线程还会拍摄在该时间点未完全处理的所有元素的快照。
现在,我想更改我的代码以支持多个消费者。所以,假设我有三个线程,一个线程将采用第一个元素,可以通过窥视操作读取。 第二个消费者线程可以用于第二个元素,但我无法检索,因为队列不支持检索第二个元素。
因此,使用标准ConcurrentLinkedQueue(我现在正在使用)的选项已经完成。
我正在考虑使用优先级队列,但是我必须将每个元素与一个标志相关联,该标志告诉我该元素是否已被某个线程使用过。
哪种数据结构最适合此问题?
答案 0 :(得分:6)
听起来你应该有两个队列:
消费者将原子地(通过锁定)从未处理的队列中拉出并添加到正在进行的队列中。这样多个消费者可以同时工作......但是生产者仍然可以在需要时拍摄两个队列的快照。当使用者完成任务时,它会将其从正在进行的队列中删除。 (这并不需要成为一个队列,因为没有任何东西可以“拉动”它。只是一些你可以轻松添加和删除的集合。)
鉴于您需要锁定以使传输原子化,您可能不需要基础队列是并发队列 - 您将保护所有共享访问。
答案 1 :(得分:0)
我同意Jon Skeet(+1),因为你需要两个商店来记录等待和正在进行的项目。我会使用LinkedBlockingQueue
并让每个消费者在其上调用take()
。当一个元素到达队列时,它将被其中一个消费者使用。
记录正在进行的操作和已完成的操作将是单独的操作。我将维护一个尚未完成的所有项目中的HashSet
,并且我的生产者将首先(原子地)将项目添加到未完成项目的HashSet中,然后在队列中弹出该项目。一旦消费者完成了它的工作,它就会从HashSet中删除该项目。
您的制作人可以扫描HashSet以确定未完成的内容。