2

私がレビューしているコード部分があります ( FindBugsを使用)。

public class MyClass{
...
private BlockedQueue q = new LinkedBlockingQueue<MyData>(1000);
private static final batchSize = 1000;

public boolean testMethod(){
    boolean done = false;
    synchronized(q){
       if(q.size == batchSize){
         q.notify();
         done = true;
       }
    }
    return done;

}

このコードで FindBugs を実行すると、次のように不平を言う -

このメソッドは、java.util.concurrent パッケージ (またはそのサブクラス) のクラスのインスタンスであるオブジェクトの同期を実行します。これらのクラスのインスタンスには、synchronized キーワードの使用とは異なり、互換性のない独自の同時実行制御メカニズムがあります。

同期されたコード部分をコメントアウトすると、synchronized(q){不平を言います-

このメソッドは、明らかにオブジェクトのロックを保持せずに Object.notify() または Object.notifyAll() を呼び出します。ロックを保持せずに notify() または notifyAll() を呼び出すと、IllegalMonitorStateException がスローされます。

FindBugs 検証に合格するには、このメソッドをどのように実装すればよいでしょうか? 上記の実装は、並行クラスの場合の通知に適していますか?

ありがとうございました。

4

3 に答える 3

3

notify()と一緒wait()に使用し、のクラスと一緒に使用しないでくださいjava.util.concurrent

BlockingQueueは、内部メカニズムを使用して、put()要素を追加するスペースがない場合、またはpoll()消費する要素がない場合にをブロックします。これを気にする必要はありません。

于 2009-10-16T17:42:41.207 に答える
0

最初のエラーは、java.util.concurrent クラス (BlockingQueue など) で基本的な同期制御を使用してはならないことを示しています。

一般に、これは同期を処理するための良い方法です。目前の問題を解決するためのより良い方法があると思います。あなたが解決しようとしている実際の問題は何ですか?

2 番目のエラーは、wait/notify/notifyAll を呼び出すために、オブジェクトのロック/モニターを (同期することによって) 所有しなければならないという事実によって発生します。

于 2009-10-16T17:33:45.123 に答える
0

BlockingQueue はシンクロナイザーオブジェクトです。状態に基づいてスレッドの制御フローを調整し、プロデューサー/コンシューマー スレッドのフローを制御します。これは、キューが目的の状態 (空でないか、いっぱいでない) になるまでブロックを取得および配置するためです。

また、同時実行プログラミングの適切な実践では、wait と notify が while ループに配置されることを前提としています。

于 2009-10-16T18:38:24.723 に答える