27

目標:特定のコードを時々実行します。

質問:パフォーマンスに関して、次の間に大きな違いがありますか?

while(true) {
    execute();
    Thread.sleep(10 * 1000);
}

executor.scheduleWithFixedDelay(runnableWithoutSleep, 0, 10, TimeUnit.SECONDS);

もちろん、後者のオプションはよりコーシャです。それでも、「Thread.sleep()に別れを告げるために、レガシーコードのリファクタリングに数日を費やす」という冒険に着手すべきかどうかを知りたいと思います。

更新:このコードは、スーパー/メガ/ハイパーハイロード環境で実行されます。

4

4 に答える 4

12

あなたは数十秒と呼ばれる睡眠時間を扱っています。ここで睡眠オプションを変更することで可能な節約は、おそらくナノ秒またはマイクロ秒です。

私は毎回後者のスタイルを好みますが、前者を持っていて、それを変更するのに多くの費用がかかる場合、「パフォーマンスの向上」は特に正当な理由ではありません。

編集再:8000スレッド

8000スレッドはひどいロットです。システムにかかる負荷の量を制御できるように、スケジュールされたエグゼキュータに移動する場合があります。ウェイクアップ時間の変更についてのあなたのポイントは注意すべきことですが、より大きなリスクは、すべてのスレッドがスリープ状態になり、次に連続してウェイクアップし、すべてのシステムリソースを奪い合うことであると主張します。

私はこれらすべてを固定スレッドプールのスケジュールされたエグゼキュータにスローするために時間を費やします。最も限られたリソース(たとえば、コア数、IOパス数など)を利用できる数と、スロップを取得するための数個だけを同時に実行します。これにより、レイテンシーを犠牲にして優れたスループットが得られます。

この方法では、何が起こっているかを制御するのが非常に難しく、スループット遅延Thread.sleep()の両方を失う可能性があります。

より詳細なアドバイスが必要な場合は、おそらく、何をしようとしているのかをより詳細に説明する必要があります。

于 2012-11-16T18:16:14.673 に答える
1

Javaのバージョンについては触れていないので、状況が変わる可能性があります。

Javaのソースコードから思い出すと、主な違いは、内部での記述方法です。

Sun Java 1.6の場合、2番目のアプローチを使用すると、ネイティブコードも待機をもたらし、システムへの呼び出しを通知します。つまり、スレッド効率が高く、CPUに優しい方法です。

しかし、再びコントロールを失い、コードの予測が難しくなります。10秒間スリープしたいと考えてください。

したがって、より予測可能性が必要な場合は、オプション1を使用できます。

また、ちなみに、レガシーシステムでは、このような問題が発生した場合、80%の確率でより良い方法がありますが、魔法数は理由(残りの20%)があるため、次のように変更してください。自身のリスク :)

于 2012-11-16T18:52:51.620 に答える
1

さまざまなシナリオがあります、

  1. タイマーは、継続的に更新されるタスクのキューを作成します。タイマーが終了すると、すぐにガベージコレクションされない場合があります。したがって、タイマーをさらに作成すると、ヒープにオブジェクトが追加されるだけです。Thread.sleep()はスレッドを一時停止するだけなので、メモリのオーバーヘッドは非常に低くなります
  2. Timer / TimerTaskはタスクの実行時間も考慮に入れるため、もう少し正確になります。また、マルチスレッドの問題(デッドロックの回避など)をより適切に処理します。
  3. スレッドが例外を取得して強制終了された場合、それは問題です。しかし、TimerTaskがそれを処理します。前回の実行での失敗に関係なく実行されます
  4. TimerTaskの利点は、意図をはるかによく表現し(つまり、コードの可読性)、cancel()機能がすでに実装されていることです。

ここから参照します

于 2017-05-23T06:22:49.800 に答える
0

あなたは「メガ...高負荷環境」で実行していると言ったので、私が正しく理解していれば、コード例のように多くのそのようなスレッドが同時にスリープしています。スレッドを強制終了して新しいスレッドを作成するよりも、スレッドを再利用する方がCPU時間は短く、リファクタリングによってスレッドを再利用できる場合があります。

1より大きいScheduledThreadPoolExecutorを使用してスレッドプールを作成できます。次に、そのスレッドプールでscheduleWithFixedDelayを呼び出すと、スレッドが使用可能な場合は再利用されます。corePoolSize

この変更により、スレッドが破棄および作成されるのではなく再利用されるため、CPU使用率が低下する可能性がありますが、低下の程度は、実行中のタスク、プール内のスレッドの数などによって異なります。一度にアイドル状態になるスレッドが少なくなるため、タスクの一部が重複します。

于 2018-12-28T15:41:08.737 に答える