1

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

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

他们是否可以在不改变 LinkedBlockingQueue 方法的情况下做到这一点?

4

3 回答 3

3

LinkedBlockingQueue 使用两个 ReenterantLocks 锁。

private final ReentrantLock putLock = new ReentrantLock();

private final ReentrantLock takeLock = new ReentrantLock();

由于这两个锁是单独的,并且 put 和 take 获取单独的锁来执行它们的操作,因此阻塞一个操作不会影响其他操作。

干杯!!

于 2013-07-19T14:22:41.833 回答
2

没有必要将消费者优先于生产者,因为它们在完全不同的条件下阻塞:如果生产者因为队列已满而被阻塞,那么消费者不会因为队列为空而被阻塞。

例如,producer1put由于队列已满而阻塞调用。Consumer1 然后执行take,它正常进行,因为队列不为空(除非您的队列的容量为 0,这将是愚蠢的) - 消费者不知道或不关心生产者的put调用被阻塞,它只关心队列不为空。

于 2013-07-19T14:14:11.673 回答
1

由于多个独立的锁,被阻塞的生产者不会阻塞消费者。

take(状态:

检索并删除此队列的头部,如有必要,等待元素可用。

put(状态:

在此队列的尾部插入指定元素,如有必要,等待空间可用

如果没有空间,那么 put 将阻塞但 take 不会被阻塞,因为它的设计仅在队列为空时等待,显然这里不是这种情况。


原评论:

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

于 2013-07-19T14:15:22.890 回答