2016-07-26 7 views
0

Я использую LinkedBlockingQueue для неявной синхронизации для моего приложения, но всегда, если я использую queue.take() или queue.poll(), первые несколько элементов как-то пропадают после получения из очереди. Я уже проверял, является ли это одним и тем же объектом.Отсутствуют первые элементы LinkedBlockingQueue

Вот мой код:

for (QueryResult result : tmpPage) { 
    String objectId = result.getPropertyValueByQueryName("cmis:objectId"); 
    writer.writeFile(objectId); //Only for debugging reasons to 
           //compare the input and the output 
    try { 
     batchJobs.offer(new Node(objectId), 1,TimeUnit.HOURS); 
    } catch(Exception e) { 
     errorLogger.error(e.getMessage()); 
    } 
} 

Место, где я беру или опрашивать

Node node = null; 
while (!nodes.isEmpty()) { 
    while((node = nodes.take())!=null) { 
     writer.writeFile(node.getObjectID()); // Only for debugging reasons 
     if (node != null) { 
      //Do some stuff 
     } 
    } 
} 

ли кто-то испытал что-то подобное?

+2

Можете ли вы пояснить «первый несколько элементов как-то пропадают после получения из очереди "? Вы имеете в виду, что после удаления элемента из очереди он больше не доступен? BTW, 'if (node! = Null)' не требуется. Вы гарантировали, что 'node! = Null' в условии вашего внутреннего цикла while. – bradimus

ответ

1

В методе получения в очереди() и poll() извлекают данные и удаляют их из очереди. Это может быть причиной потери данных. Если вы хотите получить данные, но не хотите их удалять, используйте peek().

+0

Это был мой план вывести его из очереди, но кажется, что если я использую несколько потоков в функции queue.poll() или queue.take(), некоторые элементы отсутствуют. Должен ли я установить блокировку, если я хочу вынуть что-то из очереди? Я думал, что этот класс является потокобезопасным. – Kaffi

+0

Можете ли вы рассказать мне точный сценарий, как вы это используете? Поскольку методы take() и pull() являются синхронизированными, но оба потока могут работать на одном объекте. Таким образом, данные должны быть выведены и распечатаны как threads. Есть вероятность, что переключение контекста пришло к тому же потоку, и тот же поток снова вызовет poll(), и вы бы искали нитку 2 в следующий ход. –

+0

Dear Shailesh Этот вопрос, о котором вы упомянули, на самом деле является проблемой. – Kaffi

2

Очередь представляет собой структуру данных FIFO (first in-first out). Как только вы возьмете объект из очереди, он больше не будет частью этой структуры данных. Вам придется вернуть его в очередь.

Если вы хотите посмотреть только на элемент, вы должны использовать peek().

0

Проблема была в том, о чем говорил г-н Моди.

Можете ли вы сказать мне точный сценарий, как вы используете это? Так как взять() и тянуть() являются синхронизированными методами, но оба потока могут работать на тех же Object.So данные будут должны быть выскочила и напечатаны обоими потоками. Есть вероятность, что переключение контекста пришло к тому же потоку, и тот же поток снова вызовет poll(), и вы бы искали нитку 2 в следующий ход

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