Spring 中,@Scheduled 注解的使用方法
1,395 total views, 3 views today
Spring 提供了@Scheduled 注解,良好的解决了定时任务的需求,它的实现本质是基于 java 中的 ScheduledExecutorService 类的 schedule 方法。
@Scheduled 注解标注在方法上,它是 Spring 实现的一种计划任务,可以支持如下几种方式运行:
固定时间频率运行方法。
延迟指定的时间运行方法。
按照 cron 表达式定义的时间方式运行方法。(cron 表达式的基本概念,自行查找相关材料。)
1 2 3 4 5 6 7 8 9 10 11 |
@Scheduled(fixedDelay =30000) public void doJob() { } @Scheduled(fixedRate=30000) public void doJob() { } @Scheduled(cron="0 0 * * * *") public void doJob() { } |
使用@Scheduled 注解的时,按如下步骤:
1. 配置文件中,打开运行执行 Schedule 任务的开关,使用注解
@EnableScheduling。
2. 将某个类的方法标注@Scheduled。
3. 启动 Spring 容器应用。
使用注解@EnableScheduling。
1 2 3 4 5 6 |
@Configuration @ComponentScan(value = "com.learn") @EnableScheduling public class Config { } |
在方法上标注@Scheduled。
1 2 3 4 5 6 7 |
@Component public class ScheduledTaskService { @Scheduled(fixedRate = 1000) //使用fixedRate属性每隔1秒执行 public void doJob(){ System.out.println("doJob..." + Thread.currentThread().getName() + "," + new Date()); } } |
启动 Spring 容器。
1 2 3 4 5 6 7 8 9 10 11 12 |
public static void main(String[] args) { // 使用Config.class这个配置类 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class); //防止主进程立即运行完毕,延迟10秒退出主进程 try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } applicationContext.close(); } |
结果, 每隔一秒执行一次函数。同一个线程执行:
1 2 3 4 5 6 7 8 9 10 11 |
doJob...pool-1-thread-1,Fri Sep 07 22:52:13 CST 2018 doJob...pool-1-thread-1,Fri Sep 07 22:52:14 CST 2018 doJob...pool-1-thread-1,Fri Sep 07 22:52:15 CST 2018 doJob...pool-1-thread-1,Fri Sep 07 22:52:16 CST 2018 doJob...pool-1-thread-1,Fri Sep 07 22:52:17 CST 2018 doJob...pool-1-thread-1,Fri Sep 07 22:52:18 CST 2018 doJob...pool-1-thread-1,Fri Sep 07 22:52:19 CST 2018 doJob...pool-1-thread-1,Fri Sep 07 22:52:20 CST 2018 doJob...pool-1-thread-1,Fri Sep 07 22:52:21 CST 2018 doJob...pool-1-thread-1,Fri Sep 07 22:52:22 CST 2018 doJob...pool-1-thread-1,Fri Sep 07 22:52:23 CST 2018 |
默认单线程运行
@Schduled 默认是基于单线程执行, 所有的定时任务串行执行,这就可能导致运行时间久的任务,会影响到下一个运行周期的任务。参考下图了解影响点。
图片来自于网络(https://blog.csdn.net/applebomb/article/details/52400154)
如果需要基于多线程执行,则需要配置。可以在配置文件中加入如下代码:
1 2 |
<task:annotation-driven scheduler="scheduler"/> <task:scheduler id="scheduler" pool-size="5"/> |
如上的配置用于设置线程池,这样多个定时任务就可以并行执行。
基于注解的配置方式,就是在容器中,增加一个 ScheduledThreadPoolExecutor 类型的实例即可。
1 2 3 4 5 6 7 8 |
@Configuration public class AppConfig { @Bean public ScheduledThreadPoolExecutor scheduledExecutorService() { ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5); return executor; } } |
修改一下运行任务的代码,运行 2 种任务。
1 2 3 4 5 6 7 8 9 10 11 12 |
@Component public class ScheduledTaskService { @Scheduled(fixedRate = 1000) //使用fixedRate属性每隔1秒执行 public void doJob1(){ System.out.println("doJob1..."+Thread.currentThread().getName()+","+new Date()); } @Scheduled(fixedRate = 2000) //使用fixedRate属性每隔2秒执行 public void doJob2(){ System.out.println("doJob2..."+Thread.currentThread().getName()+","+new Date()); } } |
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
doJob1...pool-1-thread-1,Fri Sep 07 22:55:00 CST 2018 doJob2...pool-1-thread-1,Fri Sep 07 22:55:00 CST 2018 doJob1...pool-1-thread-1,Fri Sep 07 22:55:01 CST 2018 doJob1...pool-1-thread-3,Fri Sep 07 22:55:02 CST 2018 doJob2...pool-1-thread-3,Fri Sep 07 22:55:02 CST 2018 doJob1...pool-1-thread-1,Fri Sep 07 22:55:03 CST 2018 doJob2...pool-1-thread-2,Fri Sep 07 22:55:04 CST 2018 doJob1...pool-1-thread-5,Fri Sep 07 22:55:04 CST 2018 doJob1...pool-1-thread-5,Fri Sep 07 22:55:05 CST 2018 doJob2...pool-1-thread-1,Fri Sep 07 22:55:06 CST 2018 doJob1...pool-1-thread-5,Fri Sep 07 22:55:06 CST 2018 doJob1...pool-1-thread-5,Fri Sep 07 22:55:07 CST 2018 doJob1...pool-1-thread-2,Fri Sep 07 22:55:08 CST 2018 doJob2...pool-1-thread-2,Fri Sep 07 22:55:08 CST 2018 doJob1...pool-1-thread-3,Fri Sep 07 22:55:09 CST 2018 doJob1...pool-1-thread-1,Fri Sep 07 22:55:10 CST 2018 doJob2...pool-1-thread-1,Fri Sep 07 22:55:10 CST 2018 |
原创文章,转载请注明出处!http://www.javathings.top/spring中scheduled注解的使用方法/