9

複数の Java スレッドを実行するアプリケーションに少し問題があります。アプリケーションは、入力キューを継続的にピークする多数の作業スレッドを実行し、キューにメッセージがある場合はそれらを取り出して処理します。

これらの作業スレッドの中には、(アプリケーションが実行されている) ホストがまだアプリケーションを実行するのに「良好な状態」にあるかどうかを確認するためのチェックを定期的に実行する予定の別の検証スレッドがあります。このスレッドAtomicBooleanは、ホストが正常かどうかを確認するためにピークを開始する前に、作業スレッドによって検証される値を更新します。

私の問題は、CPU 負荷が高い場合、検証を担当するスレッドが他のすべてのスレッドと競合する必要があるため、時間がかかることです。AtomicBoolean一定期間が経過しても更新されない場合、自動的に false に設定され、厄介なボトルネックが発生します。

私の最初のアプローチは、検証スレッドの優先度を上げることでしたが、より深く掘り下げると、これは保証された動作ではなく、アルゴリズムが正しく機能するためにスレッドの優先度に依存するべきではないことがわかりました。

代替案はありますか?ありがとう!

4

5 に答える 5

1

通常のキュー データ構造を調べる代わりに、java.util.concurrent パッケージの LinkedBlockingQueue を使用します。

できることは、スレッドのプールを実行し (実行サービスの固定スレッド プール、つまり任意の数のワーカーを使用できます)、LinkedBlockingQueue.take() を実行することです。

メッセージがキューに到着すると、待機中のスレッドの 1 つに送られます (そうです、take は、送られるものがあるまでスレッドをブロックします)。

Linked Blocking Queue の take メソッドの Java API リファレンス

HTH。

于 2013-03-01T07:29:54.910 に答える
0

条件変数を利用する必要があるようです。ピークにはCPUサイクルがかかります。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html

于 2013-02-27T15:19:46.060 に答える
0

スレッド数が多いからといって、パフォーマンスが向上するわけではありません。通常、デュアル コアを使用している場合、2 つのスレッドで最高のパフォーマンスが得られますが、3 つ以上のスレッドでは悪化し始めます。クアッド コアは 4 スレッドを処理するのが最適です。そのため、使用するスレッドの量に注意してください。

他のスレッドが作業を実行した後、他のスレッドをスリープ状態にして、他のスレッドがそれぞれの役割を果たせるようにすることができます。Thread.yield() は現在のスレッドを一時停止して、他のスレッドに時間を与えると思います。

スレッドを継続的に実行したい場合は、スレッド A と B の 2 つのメイン スレッドを作成することをお勧めします。A を検証スレッドに使用し、B から他のスレッドを作成します。したがって、スレッド A の実行時間が長くなります。

于 2013-02-26T14:37:34.130 に答える
0

ヘルス チェック スレッドをまったく使用しない (したがって、これらの問題を回避する) 作業速度を調整する古い学校のアプローチの 1 つは、キューがたとえば 100 よりも長い場合、キューに追加する要求をブロックまたは拒否することです。負荷を生成しているクライアントに動的なバック プレッシャを適用し、ワーカー スレッドが過負荷になると速度を低下させます。

このアプローチは Java 1.5 ライブラリに追加されました。java.util.concurrent.ArrayBlockingQueue を参照してください。キューがいっぱいになると、put(o) メソッドがブロックされます。

于 2013-02-26T14:40:57.813 に答える
0

Executor フレームワーク (Java の同時実行パッケージから) を使用していますか? そうでない場合は、試してみてください。検証スレッドに ScheduledExecutorService を使用してみることができます。

于 2013-02-26T14:41:30.277 に答える