5

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

消费者线程操作很慢。另外,消费者通过 peek 操作从队列中取出元素,直到消费操作完成,才能将元素从队列中移除。这是因为作为辅助操作的生产者线程还拍摄了当时未完全处理的所有元素的快照。

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

因此,使用标准 ConcurrentLinkedQueue (我现在正在使用)的选项已经取消。

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

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

4

2 回答 2

6

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

  • 未加工
  • 进行中

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

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

于 2011-04-28T09:08:46.740 回答
0

我同意 Jon Skeet (+1) 的观点,因为您需要两个商店来记录等待和进行中的项目。我会使用 aLinkedBlockingQueue并让您的每个消费者都调用take()它。当一个元素到达队列时,它将被其中一个消费者占用。

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

您的生产者可以扫描 HashSet 以确定哪些是未完成的。

于 2011-04-28T09:21:35.160 回答