Проблема с Java — LinkedBlockingQueue

#java #blockingqueue

#java #блокировка очереди

Вопрос:

 1 Очередное задание LinkedBlockingQueue = новое LinkedBlockingQueue(150);
 2 ..........
 3 .. Какой-то другой код....
 4 ..........
 5 Задание curJob = queJobs.take();
 6 ....................
 7 .. Опять какой-то другой код...
 8 ....................
 9 если (условие 1){
 10 queJobs.put(curJob);
 11 } 
 

моя проблема в том, что когда условие 1 выполняется, я возвращаю объект в очередь. но изначально это было в верхней части очереди, но после размещения оно отправится в конец очереди.
Мое требование таково:
1. Я могу вернуть элемент в начало очереди
или
2. Каким-то образом я могу подождать в строке 5, не удаляя элемент из очереди.

Ответ №1:

Очередь определена для чтения с одного конца и записи в другой конец. Итак, нет, не могу вставить его обратно. Но вместо этого вы можете использовать LinkedBlockingDeque, который более универсален в этом отношении.

Если это невозможно, вы можете использовать peek (), чтобы получить, но не удалять, curJob а позже только удалить его if (!condition1) .

Обновить

но я использую take (), потому что он блокирует выполнение до тех пор, пока очередь не опустеет.

peek (), безусловно, не будет работать для вас тогда. Но тогда я подозреваю недостаток в вашей общей логике. Обычно вам не нужно помещать задания обратно в очередь. Возможно, лучшим решением является использование другой коллекции, которая известна только рабочему потоку, куда вы помещаете задания, которые вы начали, но еще не закончили, и вы читаете из этой коллекции перед очередью заданий.

Комментарии:

1. спасибо, я думаю, LinkedBlockingDeque мне поможет. peek(), безусловно, не используется мной.

Ответ №2:

Вы можете использовать peek (), который извлекает заголовок, но не удаляет его. Затем позже проверьте, является ли condition1 ложным. Если да, то удалите ее с помощью take().

Можно добавить элемент обратно в head, но это неаккуратно. Вы можете вызвать toArray().ToList(), который поддерживает добавление с индексом 0.

Ссылка:http://download.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html

Комментарии:

1. но я использую take (), потому что он блокирует выполнение до тех пор, пока очередь не опустеет. есть второй поток, который добавляет элемент в очередь, и мне нужно остановить выполнение потока, который обрабатывает эти элементы очереди.

Ответ №3:

Более естественным решением могло бы быть использование PriorityBlockingQueue, которое позволило бы вам назначать приоритеты элементам. Это не совсем то, о чем вы просили, но это всего лишь предложение.