2016-07-26 4 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()は両方とも同期メソッドであるが、両方のスレッドが同じObjectで動作している可能性があるので、データはポップアウトされ、コンテキスト切り替えが同じスレッドに来て、同じスレッドがpoll()をもう一度呼び出すチャンスがあり、次のターンにスレッド2を探しているでしょう。 –

+0

親愛なるShailesh あなたが言及したのは実際問題でした。 – Kaffi

2

キューはFIFO(先入れ先出し)データ構造です。キューからオブジェクトを取得すると、オブジェクトはそのデータ構造の一部になりません。それをキューに戻す必要があります。

要素だけを見たい場合は、peek()を使用します。

0

問題は、Modi氏によって言及されました。

take()とpull()は両方とも同期メソッドであるが、両方のスレッドが同じオブジェクト上で動作している可能性があるため、データがポップアウトされるはずですコンテキスト切り替えが同じスレッドになって同じスレッドがpoll()を再度呼び出す可能性があります。次のターンでスレッド2を探していたでしょう

関連する問題