1.目前较为流行的两种定时任务方式:
1.开源的第三方框架: Quartz 或者 elastic-job , 但是这个比较复杂和重量级,适用于分布式场景下的定时任务,可以根据需要多实例部署定时任务(相对而言会比较大型,重量)。
2.使用Spring提供的注解: @Schedule 。 如果定时任务执行时间较短,并且比较单一,可以使用这个注解。
2.简单小案例:
存在两种调度方式: 单线程和多线程
串行方式:
使用的注解: @Scheduled 和 @EnableScheduling
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
//@EnableAsync //开启异步注解功能
@Component
//添加@EnableScheduling注解到入口类声明上面(也可以放在启动类上)
@EnableScheduling
public class ScheduledTest {
//每60S执行一次 上一次
//fixedRate 启动时间点之后 X秒执行一次
//@Async告诉Spring这是一个异步方法
@Scheduled(fixedRate = 60000)
public void satartSix() {
System.out.println("fixedRate测试:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
//initialDelay 第一次延迟 X秒执行,之后按照fixedRate的规则每X秒执行
@Scheduled(initialDelay = 60000, fixedRate = 60000)
public void satartSix1() {
System.out.println("initialDelay测试" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
//fixedDelay上一次 结束时间点之后 每X秒执行一次
@Scheduled(fixedDelay = 60000)
public void satartSix2() {
System.out.println("fixedDelay" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
//关于cron 可以通过百度cron表达式在线生成网站去生成
@Scheduled(cron = "0 */1 * * * ?")
public void satartSix3() {
System.out.println("cron" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
可以看到四个定时任务都已经执行,并且使同一个线程中串行执行,如果只有一个定时任务,这样做肯定没问题,当定时任务增多,如果一个任务卡死,会导致其他任务也无法执行。
并行方式:
当定时任务很多的时候,为了提高任务执行效率,可以采用并行方式执行定时任务,任务之间互不影响,
只要实现SchedulingConfigurer接口就可以。
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executors;
@Configuration
//所有的定时任务都放在一个线程池中,定时任务启动时使用不同的线程。
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
//设定一个长度10的定时任务线程池
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
}
}
3.个人小笔记:
1.spring的定时任务默认是单线程,若进行多任务执行可能会出现问题。
网友评论