19

10 秒ごとに実行する必要があるスレッドがあります。このスレッドには、別のサーバー上のデータベースへの複数の呼び出し (12 - 15) が含まれています。さらに、約 3 つのファイルにもアクセスします。その結果、大量の IO とネットワーク オーバーヘッドが発生します。

上記を実行するための最良の戦略は何ですか?

1 つの方法は、sleep メソッドを while ループと共に使用することですが、それは悪い設計です。

この場合、Timer に似たクラスは役に立ちますか? また、スレッドを 1 つのスレッドで実行するのではなく、複数のスレッド (IO 用と JDBC 用に 1 つ) を作成した方がよいでしょうか?

4

3 に答える 3

51

これを行うには、 ScheduledExecutorServiceが優れた方法であることがわかりました。これはおそらく より少し複雑ですがTimer、代わりに柔軟性が高くなります (たとえば、単一のスレッドまたはスレッド プールを使用することを選択できます。ミリ秒以外の単位が必要です)。

ScheduledExecutorService executor =
    Executors.newSingleThreadScheduledExecutor();

Runnable periodicTask = new Runnable() {
    public void run() {
        // Invoke method(s) to do the work
        doPeriodicWork();
    }
};

executor.scheduleAtFixedRate(periodicTask, 0, 10, TimeUnit.SECONDS);
于 2009-01-09T01:57:16.613 に答える
5

1 つのオプションは、ジョブをスケジュールできる ScheduledExecutorService を作成することです。

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ex.scheduleWithFixedDelay(...);

複数のスレッドを持つことに決めた場合は、さらに多くのスレッドを持つ ScheduledExecutorService を作成できます (これも Executors クラスを使用して)。

スレッドの数と各スレッドに入れるものに関して、パフォーマンスの観点から、これは次の要素に依存すると思います。

  • あなたの特定のアプリケーションでは、別のスレッドが I/O を待機している間に、あるスレッドが本当に「機能する」ことができますか?
  • 複数のスレッドが最終的に「同じリソースをスラッシング」し (たとえば、同じディスク上の異なる場所にあるファイルから読み取る)、互いに速度を落としますか、それとも異なるリソースに同時にアクセスしますか?
于 2009-01-09T01:56:56.567 に答える
4

TimerおよびTimerTaskクラスを見てください。それらはまさにあなたが望むものです。

コンストラクターでスレッド オブジェクトを受け取る TimerTask 実装を作成できます。

次に、run メソッドがスレッドの run メソッドを呼び出します。

// Perhaps something like this
Timer t = new Timer();
t.scheduleAtFixedRate(yourTimerTask, 0, 10 * 1000);
// Hopefully your task takes less than 12 seconds
于 2009-01-09T01:38:42.283 に答える