【Spring Boot】定时任务
【Spring Boot】定时任务
测试用业务Service
package com.example.schedule.service; import org.springframework.stereotype.Service; @Service public class UserService { public void syncUserData(){ System.out.println("syncUserData"); } } package com.example.schedule.service; import org.springframework.stereotype.Service; @Service public class StudentService { public void syncStudentData(){ System.out.println("syncStudentData"); } }
1、使用Spring的@Scheduled注解
使用@EnableScheduling注解启用Spring定时任务
package com.example.schedule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class ScheduleApplication { public static void main(String[] args) { SpringApplication.run(ScheduleApplication.class, args); } }
定时方法
package com.example.schedule.scheduled_bean; import com.example.schedule.service.StudentService; import com.example.schedule.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class YcxScheduledBean { @Autowired UserService userService; @Autowired StudentService studentService; @Scheduled(cron="*/2 * * * * ?") public void syncData() { System.out.println(">>> YcxScheduledBean"); userService.syncUserData(); studentService.syncStudentData(); } }
2、使用quartz
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
继承QuartzJobBean
package com.example.schedule.job; import com.example.schedule.service.StudentService; import com.example.schedule.service.UserService; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.quartz.QuartzJobBean; public class YcxSyncJob extends QuartzJobBean { @Autowired UserService userService; @Autowired StudentService studentService; @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { System.out.println(">>> QuartzJobBean 同步任务"); userService.syncUserData(); studentService.syncStudentData(); } }
3、@Scheduled阻塞问题
测试发现多个定时使用的相同的线程
@Scheduled(fixedRate = 1000) @Async// 不起作用 public void test1() { // 时分秒 String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")); // 日志打印 System.out.println(nowTime + " 任务【1】执行 线程:" + Thread.currentThread().getName()); } @Scheduled(fixedRate = 5000) @Async// 不起作用 public void test2() { String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")); System.out.println(nowTime + " 任务【2】执行 线程:" + Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } }
相同线程的结果。结果【1】的打印不是每个1秒,受【2】影响
解决方式,统一配置,自定义线程池
@Configuration public class ScheduledConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { // 自定义调度器,设置为一个支持定时及周期性的任务执行的线程池,这里初始3个线程 scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(5)); } }

浙公网安备 33010602011771号