#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, которое позволило бы вам назначать приоритеты элементам. Это не совсем то, о чем вы просили, но это всего лишь предложение.