2013-07-19 2 views
1

Я использую LinkedBlockingQueue вместе с шаблоном производителя/потребителя для буферизации задач. Чтобы добавить задачи в очередь, я использую метод для моих производителей: Queue.put (Object); Чтобы принять форму задачи, моя очередь, которую я использую для своих потребителей: Queue.take (Object);Как отдать предпочтение потребителям при использовании LinkedBlockingQueue?

Я нашел в Java api, что оба этих метода будут блокироваться до тех пор, пока очередь не станет доступной. Моя проблема: я знаю, что в моей системе больше производителей задач, чем потребителей. И все мои задачи должны быть обработаны. Поэтому мне нужно, чтобы мои потребители, когда они были заблокированы, имели приоритет над производителями, чтобы получить очередь.

Это их способ сделать это без значительного изменения методов LinkedBlockingQueue?

+0

Насколько я знаю, эта очередь по дизайну не будет блокировать потребителей, даже если производители заблокированы из-за того, что очередь заполнена. – hexafraction

ответ

3

В LinkedBlockingQueue используется два замка ReenterantLocks.

private final ReentrantLock putLock = new ReentrantLock();

private final ReentrantLock takeLock = new ReentrantLock();

Так как замки индивидуальные и поставить и принять aquires раздельные замки для выполнения своих операционных блокирующих одну операции не будут влиять на другие операции.

Cheers !!

+1

, так что очередь может быть доступна одновременно производителем и потребителем ?! Ну спасибо, за быстрый ответ! – Don

+0

Да! Однако есть некоторые другие операции, которые полностью блокируют очередь для чтения и записи. например если вы вызываете метод toArray или clear. –

2

Нет необходимости уделять приоритетное внимание потребителям по отношению к производителям, поскольку они блокируются в совершенно разных условиях: если производитель заблокирован, потому что очередь заполнена, то потребители не будут заблокированы в результате того, что очередь пуста.

Например, у производителя1 есть заблокированный вызов put, потому что очередь заполнена. Затем Consumer1 выполняет take, что происходит как обычно, потому что очередь не пуста (если ваша очередь не имеет 0, что было бы глупо) - потребитель не знает или не заботится о том, что звонок производителя put заблокирован, все, что он заботится о том, что очередь не пуста.

1

производители блокируются не блокирует потребителей из-за нескольких независимых замков.

take( состояния:

Извлекает и удаляет главу этой очереди, ожидая в случае необходимости, пока элемент не станет доступным.

put( состояние:

Вставляет указанный элемент в хвосте этой очереди, ожидая в случае необходимости для пространства, чтобы стать доступным

Если нет никакого места, то положить будет блокировать но take не будет заблокирован, так как это по дизайну, ожидая, только если очередь пуста, очевидно, не здесь.


Оригинальный комментарий:

Насколько я знаю, эта очередь, дизайн, не будет блокировать потребителей, даже если производители будут заблокированы из-за очереди не полный.

Смежные вопросы