Java 为生产者-消费者问题的变体选择数据结构

Java 为生产者-消费者问题的变体选择数据结构,java,data-structures,producer-consumer,Java,Data Structures,Producer Consumer,现在,我有一个队列,有多个生产者和一个消费者 使用者线程操作缓慢。此外,使用者通过peek操作从队列中获取元素,并且在消费操作完成之前,不能从队列中移除该元素。这是因为生产者线程作为一个辅助操作,也会获取在该时间点未完全处理的所有元素的快照 现在,我想更改代码以支持多个使用者。所以,假设我有三个线程,一个线程将获取第一个元素,它可以通过peek操作读取。 第二个使用者线程可以检索第二个元素,但我无法检索,因为队列不支持检索第二个元素 因此,使用标准ConcurrentLinkedQueue(我现

现在,我有一个队列,有多个生产者和一个消费者

使用者线程操作缓慢。此外,使用者通过peek操作从队列中获取元素,并且在消费操作完成之前,不能从队列中移除该元素。这是因为生产者线程作为一个辅助操作,也会获取在该时间点未完全处理的所有元素的快照

现在,我想更改代码以支持多个使用者。所以,假设我有三个线程,一个线程将获取第一个元素,它可以通过peek操作读取。 第二个使用者线程可以检索第二个元素,但我无法检索,因为队列不支持检索第二个元素

因此,使用标准ConcurrentLinkedQueue(我现在正在使用)的选项已经过时了

我正在考虑使用一个优先级队列,但随后我必须将一个标志与每个元素相关联,该标志告诉我该元素是否已被某个线程使用


哪个数据结构最适合这个问题

听起来你真的应该有两个队列:

  • 未加工
  • 进行中
使用者将以原子方式(通过锁)从未处理队列中拉出并添加到正在处理的队列中。这样多个消费者可以同时工作。。。但生产者仍可以在需要时拍摄两个队列的快照。当使用者完成任务时,它会将其从正在进行的队列中删除。(这实际上不需要是一个队列,因为没有任何东西会从队列中“拉”出来。只需要一些可以轻松添加和删除的集合。)

考虑到您需要锁定以使传输原子化,您可能不需要底层队列成为并发队列-您已经在保护所有共享访问。

我同意Jon Skeet(+1)的观点,因为您需要两个存储来记录等待和正在进行的项。我会使用
LinkedBlockingQueue
,让您的每个消费者调用
take()
。当一个元素到达队列时,它将由一个使用者获取

记录进行中的内容和完成的内容将是单独的操作。我将维护所有尚未完成的项目的
HashSet
,我的制作人将首先(原子地)将项目添加到未完成项目的HashSet中,然后将项目弹出队列。一旦消费者完成了它的工作,它就会从哈希集中删除该项

您的制作人可以扫描哈希集以确定哪些是未完成的