2012-05-10 12 views
3

BlockingQueue内のすべての未処理作業が処理されるまでブロックするメソッドを提供する必要があります。Java無制限カウント・セマフォ?

私は、0で始まるカウントされたセマフォでこれを処理できると思っていました。アイテムがキューに追加され、それらが完了すると増分するにつれ減少します。 finish()はセマフォを取得し、再び解放して終了します。

おそらくreducePermits()を呼び出すことができます。許可カウントがすでに<になっていれば、これは機能しますか?保護されているので、セマフォークラスを拡張して機能させる必要があります。

私の次善のアイデアは、ループ内のキューの内容をチェックし、チェックの間に100msほどスリープすることです。それは動作しますが、クルージュのようです。

これは意味がありますか?誰もが簡単で清潔な方法を提案していますか?

TIA、 - Tim。

public MyClass { 
    public class MySemaphore extends Semaphore { 
    public void seize() { 
     reducePermits(1); 
    } 
    } 
    private MySemaphore allDone = new MySemaphore(); 
    void startSomething() { 
    allDone.seize(); 
    } 
    void finishSomething() { 
    allDone.release(); 
    } 
    void finish() { 
    allDone.acquire(); 
    allDone.release(); 
    } 
} 
+0

解決しようとしている問題はわかりませんが、CompletionServiceが機能するかどうかを確認してください(http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent /CompletionService.html)。 –

+0

yup、あるいは何をしようとしているのかに応じて、 'CountdownLatch' http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.htmlを参照してください。 (ユースケースについてさらに説明しますか?) – andersoj

+1

ありがとう、私もそれらのことを考えましたが、彼らは私のためにはうまくいきませんでした。 CompletionService and Future 彼らは出口の別々のスレッドを扱うように。私は終了しない作業のバッチを処理する単一のスレッドを持っています。 CountdownLatchは、カウントダウンしている既知の数の要素を想定しています。私は、任意の数のアイテムを待つ必要があり、すべてが完了したらアンブックする必要があります。 – tbroberg

答えて

2

あなたは、その後、その後、最終的な処理(おそらく先物などを経由して)すべての項目に自分自身を処理呼び出し、drainTo(collection)を呼び出すことにより、キューを排出できます。

+0

これは意味があります。私がすでにこのようにしなかった唯一の理由は、並行性の問題が私を緊張させることです。問題が発生した場合、デバッグするのは醜いでしょう。私はちょうど編集的であると思う。 LinkedBlockingQueueのさまざまなメソッド間に並行処理の問題があってはなりませんか? – tbroberg

+0

いくつかの考えの後で、なぜこれが私にとってうまくいかないのか分かります。実際のユースケースでは、キューの各項目の処理は、結果を出力ストリームに書き出すことを含みます。各項目は完全に処理してから次の処理を開始できるので、ワーカースレッドがアクティブな状態でキューから項目を取得して別のスレッドで作業を開始することはできません。良い答え、私はちょうど質問でこれを指定していない。 – tbroberg

+0

これらを順番に処理する必要がある場合は、処理を実行するワーカースレッドを1つだけにしてください。 – Bohemian