ネットワーク ストレス テスト ツールを開発するプロジェクトでは、パケットをサブネット全体にフラッディングします。ポートとブロードキャスト アドレスを受け取り、while(!Thread.currentThread().isInterrupted) ループで特定のパケットを送信する Runnable クラスがあります。次に、すべてのネットワーク インターフェイスとすべての可能なポートを反復処理するメイン クラスを作成し、1000 スレッド固定プールを使用して Runnable クラスを ExecutorService に追加します。問題は、ExecutorService が現在の 1000 スレッドの処理が終了するのを待っている場合、while ループにあるため、決して終了しないことです。ただし、すべての単一スレッド (65536 * インターフェイスの数) を開始すると、大量のメモリが消費されます。スレッドを循環させる方法を探しているので、すべてのスレッドがしばらくの間動作し、高いネットワーク出力を維持しながらメモリを節約できます。
2 に答える
各スレッドを常に完了または「永久に」実行するのではなく、スレッドに明確に定義された小さな作業セットを実行させてから、それらをエグゼキュータに再度追加します。この高レベルの管理は、実行するステップの新しい範囲でエグゼキュータ キューにタスクを再追加することを管理する「コントローラ」スタイル オブジェクトによって行うことができます。
たとえば、各タスクに繰り返し実行する 1000 のステップがある場合: - タスク 1 はステップ 1 から 100 を実行し、ステップ 101 から 200 のエグゼキュータ キューに自身を追加して終了します - タスク 2 は同様に実行 (および終了) する機会を得ます- タスク 1 は現在キューの次であるため、101 から 200 を実行し、201 から 300 のエグゼキューター キューに追加されます。- タスク 1 が最後に到達するまで - 901-1000 - その後、実行を継続したい場合は、1-100 に戻ります。
あなたの場合、さまざまなステップがポートである可能性があり、さまざまなスレッドがさまざまなブロードキャストアドレスを表しています-必要に応じて分割してください。
より多くのスレッドが常により高いスループットをもたらすという誤解に苦しんでいる可能性があると思います。多くの場合、そうではありません。
アプリケーションは、CPU バウンドになるか、ネットワーク カードのスループットに制約される可能性があります。これらのリソースをめぐって競合する何万ものスレッドを OS にジャグリングさせても、スループットは向上しません。多数のスレッドが役立つのは、スレッドが寿命のほとんどを大容量の外部リソース (データベースなど) の待機に費やしている場合のみです。パケットをブラストするだけで (おそらく) 応答に関心がないため、自然な待機ポイントはありません。
プロセッサやネットワーク カード (いずれか小さい方) と同じ数のスレッドのみを使用することをお勧めします。