2011-12-16 8 views
0

私はLinkedBlockingQueue何百万もの文字列を巡っています。 読み取りスレッドは、ソースに項目がなくなったときに実行を終了する必要があります。LinkedBlockingQueueの "escape"要素

"SHUTDOWN"のようなダミーの値をLinkedBlockingQueueに入れることを考えました。

読者は、この処理を行います。

while ((data = (String)MyLinkedBlockingQueue.take()).equals("SHUTDOWN") == false) { 
    //read and live 
} 

は、すべての文字列に等号を実行することが効率的ですか?代わりに私は何を使うことができますか?

答えて

2

あなたは正しい方向にあります。これはBlockingQueueの処理を終えるための標準的なイディオムであり、 "poison pill"と呼ばれています。私は通常、特別なプライベート静的最終インスタンスを使用してそれを実装するので、オブジェクトの平等性を実現し、実際の価値と重複するリスクはありません。例:

private static final String SHUTDOWN = new String("SHUTDOWN"); // use new String() so you don't get an interned value 

public void readQueue() { 
    while ((data = (String)MyLinkedBlockingQueue.take()) != SHUTDOWN) { 
     //read and live 
    } 
} 

public void shutdownQueue() { 
    MyLinkedBlockingQueue.put(SHUTDOWN); 
} 
+0

これは、キューをシャットダウンする唯一の方法が 'shutdownQueue()'を呼び出すことであるという副作用があることに注意してください。逆に、文字列リテラル(および/または 'intern()')を使用すると、誰も 'put(" SHUTDOWN ")'を呼び出すことによってキューをシャットダウンすることができます。あなたが望むものは、あなたが意図するセマンティクスに依存します。 –

+0

@DanielPryden - 誰も 'shutdownQueue()'を呼び出してキューをシャットダウンすることができます。この方法では、キュー管理ロジックをうまくカプセル化した状態に保ちます。 – jtahlborn

+0

@jtahlborn、なぜ私は拘束された文字列を使用できないのか説明できますか? – jullin

0

poll()を使用し、nullを返すときにループを終了すると考えることもできます。

+0

ない良い、キューがしばらくの間アイドル状態になることができますので、しかし、ソースは置くより多くのデータを持っています。 – jullin

+0

あなたがequals()の効率を心配しているのなら、SHUTDOWNを定数にして比較のために '=='を使うのはなぜですか? –

0

これは、「毒薬」を毎回確認する必要がないように実装できます。 LinkedBlockingQueueで動作するThreadPoolExecutorを使用することを検討してください。処理をシャットダウンする場合は、executorオブジェクトのshutdown()メソッドを呼び出します。そのメソッドのドキュメントから:

は以前に提出したタスクが を実行される通常のシャットダウンを開始しますが、新しいタスクは受け入れられません。すでにシャットダウンされている場合は、呼び出しに の追加効果はありません。

あなたはタスクがまだキューに保留されている間、すぐに処理を停止するに興味があるなら、この記事を参照してください:With a Java ExecutorService, how do I complete actively executing tasks but halt the processing of waiting tasks?

関連する問題