之前做php的时候,如果想做个定时任务,或者想特定时间调用某个脚本/接口,我们都会考虑使用linux的crontab来实现,比较对于单线程脚本语言来说,做定时不是那么容易
然后最近因为开始学习java,就用到了springboot这个框架中的定时任务,所以记录下使用定时任务的步骤
主类application中开启@EnableScheduling 注解
建立定时任务配置类,配置定时计划,定时要做的任务
@Component public class ScheduledTask { val logger = LoggerFactory.getLogger(UserService::class.java) @Scheduled(cron = "0/5 * * * * ?") fun scheduled1() { val now = Timestamp.from(Instant.now()) logger.info("定时任务调起 ${now}") } }
然后run,你会发现你写的定时任务会自己跑起来了
当你写了主类中加了@EnableAsync,且第二步中的配置函数加了@Async,就是多线程了
注意,如果主类中你没有写@EnableAsync 的话,此时的定时任务是单线程的,是不是惊喜+意外,我们来证实一下
先试试多线程
import com.chocwell.blog.api.service.UserService import org.slf4j.LoggerFactory import org.springframework.scheduling.annotation.Async import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.sql.Timestamp import java.time.Instant @Component public class ScheduledTask { val logger = LoggerFactory.getLogger(UserService::class.java) @Async @Scheduled(fixedDelay = 1000) fun scheduled1() { val now = Timestamp.from(Instant.now()) logger.info("定时任务1调起 ${now}") Thread.sleep(5000) } @Async @Scheduled(fixedDelay = 2000) fun scheduled2() { val now = Timestamp.from(Instant.now()) logger.info("定时任务2调起 ${now}") Thread.sleep(5000) } }
运行结果
这样你的定时任务1和2就互不干扰,并且单个任务的被调用的时间和其执行时间无关,因为每次运行都是一个新线程,可以看到sleep并没有影响定时任务的执行
注:使用了fixedDelay ,意思是上一次开始执行时间点之后多久开始执行下次任务
接来下,我们试试单线程,把@Async去掉试一下,清楚的看到,每次的任务都受sleep的影响
好了,这次的学习我学到了定时任务不是只有linux的crontab,springboot下的定时同样好用