web-dev-qa-db-ja.com

Springでスケジュールの重複を防ぐ方法は?

@Scheduled(fixedDelay = 5000)
public void myJob() {
     Thread.sleep(12000);
}

前のルーチンがまだ終了していない場合、この春のジョブが実行されないようにするにはどうすればよいですか?

32
membersound

fixedDelayを使用すると、期間はジョブの完了後に測定されるため、心配はありません。

29

デフォルトでは、springはシングルスレッドのExecutorを使用します。したがって、2つの@Scheduledタスクが重複することはありません。完全に無関係なクラスの2つの@Scheduledメソッドでさえ、すべての@Scheduledタスクを実行するスレッドが1つしかないため単純にオーバーラップしません。

さらに、デフォルトのエグゼキューターをスレッドプールベースのエグゼキューターに置き換えても、それらのエグゼキューターは通常、以前にスケジュールされたインスタンスが完了するまでタスクインスタンスの実行を遅らせます。これは、fixedDelay、fixedInterval、およびcronベースのスケジュールに当てはまります。たとえば、このスプリング構成では、スレッドプールを使用するScheduledThreadPoolExecutorが作成されますが、同じスケジュールの同時インスタンスは必要に応じて許可されません。

@Configuration
@EnableScheduling
...
public class MySpringJavaConfig {
    @Bean(destroyMethod = "shutdown")
    public Executor taskScheduler() {
        return Executors.newScheduledThreadPool(5);
    }
    ...
}

ScheduledThreadPoolExecutor :: scheduleAtFixedRateのjavadoc は次を指定します。

このタスクの実行にその期間よりも長い時間がかかる場合、後続の実行は遅く開始される場合がありますが、同時に実行されません。

注:この機能は、@ Asyncタスクには当てはまりません。 springは、必要な数の同時インスタンスを作成します(プールに十分なスレッドがある場合)。

67
james turner