2016-07-26 53 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

你可以澄清“第一个从队列中获得它之后很少有元素会丢失“?你的意思是说,从队列中移除元素后,它不再可用?顺便说一下,'if(node!= null)'是不需要的。你在内部'while'循环的条件下保证'node!= null'。 – bradimus

回答

1

在队列中,take()和poll()方法检索数据并将其从队列中移除。这可能是您丢失数据的原因。如果您想检索数据但不想删除它,请使用peek()。

+0

这是我计划将它从队列中取出,但似乎如果我在queue.poll()或queue.take()函数上使用多个线程,则会丢失一些元素。如果我想从队列中取出某些东西,我是否必须设置锁定?我认为这个课程是线程安全的。 – Kaffi

+0

你能告诉我你使用这个方法的确切场景吗?既然take()和pull()都是同步方法,但是两个线程都可能在同一个对象上工作。所以数据将被弹出并由有机会,上下文切换到同一个线程和同一个线程再次调用poll(),你会在下一回合中寻找线程2。 –

+0

亲爱的Shailesh 你提到的那种情况实际上是问题所在。 – Kaffi

2

队列是一个FIFO(先入先出)数据结构。一旦从队列中取出一个对象,它将不再是该数据结构的一部分。你将不得不把它放回队列中。

如果你只想看看元素,你会想使用一个peek()。

0

问题是莫迪先生提到的。

能否告诉我具体的使用方法?由于take()和pull()都是同步方法,但两个线程都可能在同一个Object上工作,所以数据应该弹出并由两个线程打印。有机会,上下文切换到同一个线程和相同的线程再次调用poll(),你会一直在寻找线程2在下一回合