@Scheduledで同時実行する
Spring Bootではメソッドに@Scheduledをつけると簡単にタスク処理を書くことができます。
ところがこのタスクは複数のメソッドにつけるとお互い排他で動作するようです。
・fixedDelayはtask終了後に起動する時間(ミリ秒)を指定
・ほかにもcron指定などできるので、「Spring Bootでtaskを定期実行する方法」の記事などを参考にしてください
・ちなみにこういった値は設定値に書きたくなるのが世の常ですなので、application.propertiesに書くこともできます
@Scheduled(initialDelayString="\${foo}", fixedDelayString="\${bar}")
groovyだとJavaとことなりエスケープがいるので注意が必要ですね!
・実行結果
・これでは困ることがあるので、同時実行できるように修正します
ところがこのタスクは複数のメソッドにつけるとお互い排他で動作するようです。
[広告]
[広告]
まずは排他動作を確認
・sample.app.product.ProductTask.groovyを作成
package sample.app.product
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Component
@Component
class ProductTask {
private static final Logger log = LoggerFactory.getLogger(this)
@Scheduled(initialDelay=3000L, fixedDelay=1000L)
void execute1() {
log.info("execute1 start")
sleep(10 * 1000) // 10秒スリープ
log.info("execute1 end")
}
@Scheduled(initialDelay=3000L, fixedDelay=1000L)
void execute2() {
log.info("execute2 start")
sleep(1 * 1000) // 1秒スリープ
log.info("execute2 end")
}
}
・initialDelayはspring boot起動後に最初に実行するまでの時間(ミリ秒)を指定・fixedDelayはtask終了後に起動する時間(ミリ秒)を指定
・ほかにもcron指定などできるので、「Spring Bootでtaskを定期実行する方法」の記事などを参考にしてください
・ちなみにこういった値は設定値に書きたくなるのが世の常ですなので、application.propertiesに書くこともできます
@Scheduled(initialDelayString="\${foo}", fixedDelayString="\${bar}")
groovyだとJavaとことなりエスケープがいるので注意が必要ですね!
・実行結果
2017-10-14 15:56:44.285 INFO 10244 --- [pool-2-thread-1] sample.app.product.ProductTask : execute2 start 2017-10-14 15:56:45.285 INFO 10244 --- [pool-2-thread-1] sample.app.product.ProductTask : execute2 end 2017-10-14 15:56:45.286 INFO 10244 --- [pool-2-thread-1] sample.app.product.ProductTask : execute1 start 2017-10-14 15:56:55.287 INFO 10244 --- [pool-2-thread-1] sample.app.product.ProductTask : execute1 end 2017-10-14 15:56:55.288 INFO 10244 --- [pool-2-thread-1] sample.app.product.ProductTask : execute2 start 2017-10-14 15:56:56.291 INFO 10244 --- [pool-2-thread-1] sample.app.product.ProductTask : execute2 end・execute1が実行中の10秒間は、execute2が実行できてないですね
・これでは困ることがあるので、同時実行できるように修正します
@Scheduledを同時実行できるように設定
・sample.app.common.AppConfig.groovyを作成
package monitor.app.common
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.scheduling.annotation.EnableScheduling
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
@Configuration
class AppConfig {
@Bean(destroyMethod = "shutdown")
ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler()
taskScheduler.poolSize = 10
return taskScheduler
}
}
・実行結果2017-10-14 16:35:33.714 INFO 9792 --- [taskScheduler-1] sample.app.product.ProductTask : execute1 start 2017-10-14 16:35:33.714 INFO 9792 --- [taskScheduler-2] sample.app.product.ProductTask : execute2 start 2017-10-14 16:35:34.733 INFO 9792 --- [taskScheduler-2] sample.app.product.ProductTask : execute2 end 2017-10-14 16:35:35.735 INFO 9792 --- [taskScheduler-2] sample.app.product.ProductTask : execute2 start 2017-10-14 16:35:36.736 INFO 9792 --- [taskScheduler-2] sample.app.product.ProductTask : execute2 end 2017-10-14 16:35:37.738 INFO 9792 --- [taskScheduler-3] sample.app.product.ProductTask : execute2 start 2017-10-14 16:35:38.739 INFO 9792 --- [taskScheduler-3] sample.app.product.ProductTask : execute2 end 2017-10-14 16:35:39.741 INFO 9792 --- [taskScheduler-2] sample.app.product.ProductTask : execute2 start 2017-10-14 16:35:40.742 INFO 9792 --- [taskScheduler-2] sample.app.product.ProductTask : execute2 end 2017-10-14 16:35:41.744 INFO 9792 --- [taskScheduler-4] sample.app.product.ProductTask : execute2 start 2017-10-14 16:35:42.755 INFO 9792 --- [taskScheduler-4] sample.app.product.ProductTask : execute2 end 2017-10-14 16:35:43.731 INFO 9792 --- [taskScheduler-1] sample.app.product.ProductTask : execute1 end・無事にexecute1が実行中もexecute2が別スレッドで実行できていますね!
コメントを残す