使用LinkedBlockingQueue时如何优先考虑消费者?

时间:2013-07-19 14:11:52

标签: java concurrency

我正在使用LinkedBlockingQueue和生产者/消费者模式来缓冲任务。要将任务添加到队列,我使用我的生产者的方法:Queue.put(Object);要从我的队列中获取任务,我将为消费者使用:Queue.take(Object);

我在Java api中发现这两种方法都会阻塞,直到队列变得可用。我的问题是:我知道我的系统中有更多的任务生成者,然后是消费者。我的所有任务都需要处理。因此,我需要我的消费者在被阻止时优先于生产者获取队列。

他们是否可以在不更改LinkedBlockingQueue的方法的情况下执行此操作?

3 个答案:

答案 0 :(得分:3)

LinkedBlockingQueue使用两个ReenterantLocks锁。

private final ReentrantLock putLock = new ReentrantLock();

private final ReentrantLock takeLock = new ReentrantLock();

由于两个锁是分开的并且放置并且需要单独的锁来执行它们的操作阻塞,因此一个操作不会影响其他操作。

干杯!!

答案 1 :(得分:2)

没有必要优先考虑消费者而不是生产者,因为他们在完全不同的条件下阻止:如果生产者因队列已满而被阻止,那么消费者将不会因为队列为空而被阻止。 / p>

例如,producer1有一个阻塞的put调用,因为队列已满。然后,Consumer1执行take,这正常进行,因为队列不为空(除非您的队列容量为0,这将是愚蠢的) - 消费者不知道或不关心生产者的{{1} } call被阻止,它关心的是队列不是空的。

答案 2 :(得分:1)

被阻止的生产者不会因多个独立锁而阻止消费者。

take(州:

  

检索并删除此队列的头部,必要时等待,直到元素可用为止。

put(州:

  

将指定的元素插入此队列的尾部,等待空间变为可用

如果没有空格,那么put会阻塞,但是不会被阻塞,因为它只是在队列为空的情况下等待,显然不是这里的情况。


原始评论:

  

据我所知,这个队列按设计不会阻止消费者,即使生产者由于队列已满而被阻止。