2

@Scheduled アノテーションを持つクラスにメソッドがあります

@Scheduled(cron = "* * * * * *")
public void doSomething() {

}

これは毎秒実行されます (cron ステートメントが正しいと仮定します)。

私はsping設定を次のように設定しています

<task:scheduler id="taskScheduler" pool-size="2" />
<task:executor id="taskExecutor" pool-size="2" />
<task:annotation-driven executor="taskExecutor" scheduler="taskScheduler" />

問題は、最後の実行が完了するまでメソッドが再起動されないことです。私はそれが 2 回起動することを期待していました (そして、どこかでジョブ キューがいっぱいになり始める可能性があります)。

メソッド呼び出し間の依存関係を削除するにはどうすればよいですか。ただし、一度に実行されるプロセスは 2 つだけです。

4

3 に答える 3

0

スケジューラ スレッドがタスクの実行でビジーであるため、新しい実行はトリガーされません。

求めている動作を実現するには、タスクをエグゼキュータ スレッドに委譲します。これを行う最も簡単な方法は、@Async でメソッドにアノテーションを付けることです。

@Scheduled(cron = "* * * * * *")
@Async
public void doSomething() {
   ...
}

ただし、並行して実行される十分なエグゼキュータ スレッドに対応するには、タスク エグゼキュータ プールのサイズを必要な容量に調整する必要があることに注意してください。

于 2016-02-26T20:42:43.723 に答える
0

実際の作業を taskExecutor に貼り付けることが考えられるようです

@Scheduled(cron = "* * * * * *")
 public void doSomething() {
   this.executor.execute(new Runnable() {...}
 }

次に拒否ポリシーを *CALLER_RUNS* として追加します

<task:scheduler id="taskScheduler" pool-size="1" />
<task:executor id="taskExecutor" pool-size="1"
    queue-capacity="1" rejection-policy="CALLER_RUNS" />
<task:annotation-driven executor="taskExecutor"
    scheduler="taskScheduler" />

したがって、上記の場合、作業は常に 1 つのスレッド プールによって行われます。

これが最善の方法かどうかはわかりません。

于 2013-02-22T17:41:11.200 に答える
-1

またはの代わりに-valueを使用@Scheduledしてみてください:fixedRatecronfixedDelay

fixedRate 呼び出しの間隔を固定して注釈付きメソッドを実行します。

fixedDelay 最後の呼び出しの終了から次の呼び出しの開始までの期間を固定して、注釈付きメソッドを実行します。

fixedRateを使用すると、メソッドの別の実行が、タスクが最後に開始されてから一定の時間後に発生するようにスケジュールされます。

fixedDelayを使用すると、タスクが最後に終了してから一定時間後に次の呼び出しが発生します。

当然、タスクを時間どおりに実行するには、スレッドプールに別の空きスレッドが必要です(前のスレッドがまだ実行中の場合)。

于 2013-02-23T10:17:19.443 に答える