3

アトミックなロックフリーの方法でConcurrentLinkedQueueを使用したい:

複数の同時スレッドがイベントをキューにプッシュし、他のスレッドがそれらを処理します。キューはバインドされておらず、スレッドを待機させたりロックしたりしたくありません。ただし、読み取り部分は、キューが空になったことに気付く場合があります。ロックフリーの実装では、読み取りスレッドはブロックしてはなりませんが、そのタスクを終了し、他のタスクの実行を続行します (つまり、ExecutorService として)。したがって、最初の新しいイベントを空のキューにプッシュするライターは、それを認識し、リーダーを再起動して (つまり、新しい Runnable を ExecutorService に送信して) キューを処理する必要があります。2 番目または 3 番目のイベントを送信するそれ以降のスレッドは、一部のリーダーが既に準備/送信されていると想定する可能性があるため、気にしません。

残念ながら、ConcurrentLinkedQueue のadd()メソッドは常に true を返します。イベントを追加する前または後に isEmpty() をキューに問い合わせても、アトミックではないため役に立ちません。queue size() を監視するために追加の AtomicInteger を使用する必要がありますか、それともよりスマートなソリューションがありますか?

ディーター。

4

2 に答える 2

2

ExecutorServiceこれに直接を使用しない理由がよくわかりません。内部でを使用し、BlockingQueueすべてのシグナリング自体を処理します。

// open ended thread pool
ExecutorService threadPool = Executors.newFixedThreadPool(1);
for (Job job : jobsToDo) {
    threadPool.submit(new MyJobProcessor(job));
}

正当な理由がない限り、同じロジックを自分で書き直すことはありません。

休眠スレッドを何らかの方法で利用しようとしている場合は、気にしないことを強くお勧めします。スレッドは比較的安価なので、キューに入れられたタスクを処理するためにスレッドを割り当てることは問題ありません。スレッドの再利用は不要であり、時期尚早の最適化のように思えます。

于 2012-07-25T17:22:01.213 に答える
1

送信競合の解決に を使用すると、ロックやブロックAtomicIntegerよりも効率的です。synchronized

于 2012-07-26T02:45:38.987 に答える