导读


由于项目需要,需要使用定时任务推送数据,而且有时候需要开启多个定时任务去跑,后面研究了下定时任务的操作技能,有两张,一种是异步的(推荐),线程安全,一种不是异步的,非线程安全,假如有一个挂了,会影响后面输出。

使用


说明

SpringBoot项目开启定时任务,需要在启动类上添加注解 @EnableScheduling ,不然的话,就算项目启动,定时任务还是不可以使用。

异步定时任务

异步配置类

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.scheduling.annotation.EnableAsync;
  4. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  5. import java.util.concurrent.Executor;
  6. import java.util.concurrent.ThreadPoolExecutor;
  7. /**
  8. * 异步开启定时任务配置
  9. *
  10. * @date 2020/6/24 15:46
  11. */
  12. @Configuration
  13. @EnableAsync //开启异步事件的支持
  14. public class AsyncConfig {
  15. /**
  16. * 核心线程数
  17. */
  18. private int corePoolSize = 20;
  19. /**
  20. * 最大线程数
  21. */
  22. private int maxPoolSize = 220;
  23. /**
  24. * 队列最大长度
  25. */
  26. private int queueCapacity = 20;
  27. /**
  28. * 线程池维护线程所允许的空闲时间
  29. */
  30. private int keepAliveSeconds = 20;
  31. /**
  32. * 线程池对拒绝任务(无线程可用)的处理策略
  33. * <p>
  34. * rejectedExectutionHandler参数字段用于配置绝策略,常用拒绝策略如下
  35. * <p>
  36. * AbortPolicy:用于被拒绝任务的处理程序,它将抛出RejectedExecutionException
  37. * <p>
  38. * CallerRunsPolicy:用于被拒绝任务的处理程序,它直接在execute方法的调用线程中运行被拒绝的任务。
  39. * <p>
  40. * DiscardOldestPolicy:用于被拒绝任务的处理程序,它放弃最旧的未处理请求,然后重试execute。
  41. * <p>
  42. * DiscardPolicy:用于被拒绝任务的处理程序,默认情况下它将丢弃被拒绝的任务。
  43. */
  44. private ThreadPoolExecutor.AbortPolicy rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
  45. @Bean
  46. public Executor taskExecutor() {
  47. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  48. executor.setCorePoolSize(corePoolSize);
  49. executor.setMaxPoolSize(maxPoolSize);
  50. executor.setQueueCapacity(queueCapacity);
  51. executor.setKeepAliveSeconds(keepAliveSeconds);
  52. executor.setRejectedExecutionHandler(rejectedExecutionHandler);
  53. executor.initialize();
  54. return executor;
  55. }
  56. }

启动定时任务

  1. import org.slf4j.Logger;
  2. import org.slf4j.LoggerFactory;
  3. import org.springframework.scheduling.annotation.Async;
  4. import org.springframework.scheduling.annotation.Scheduled;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. * 异步开启定时任务
  8. *
  9. * @date 2020/6/24 15:46
  10. */
  11. @Component
  12. @Async //启动异步调用
  13. public class TinfoDemoScheduleTask {
  14. private static final Logger logger = LoggerFactory.getLogger(TinfoDemoScheduleTask.class);
  15. @Scheduled(cron = "0/1 * * * * *")
  16. public void scheduled() {
  17. logger.info("测试cron表达式,线程名称:{}", Thread.currentThread().getName());
  18. }
  19. @Scheduled(fixedRate = 1000)
  20. public void scheduledDemo1() {
  21. logger.info("测试fixedRate,线程名称:{}", Thread.currentThread().getName());
  22. }
  23. @Scheduled(fixedDelay = 1000)
  24. public void scheduledDemo2() {
  25. logger.info("测试fixedDelay,线程名称:{}", Thread.currentThread().getName());
  26. }
  27. }

Console

  1. 2020-06-24 15:51:17.506 INFO 17092 --- [ taskExecutor-1] c.l.u.i.demo.TinfoDemoScheduleTask : 测试fixedRate,线程名称:taskExecutor-1
  2. 2020-06-24 15:51:17.506 INFO 17092 --- [ taskExecutor-2] c.l.u.i.demo.TinfoDemoScheduleTask : 测试fixedDelay,线程名称:taskExecutor-2
  3. 2020-06-24 15:51:18.001 INFO 17092 --- [ taskExecutor-3] c.l.u.i.demo.TinfoDemoScheduleTask : 测试cron表达式,线程名称:taskExecutor-3
  4. 2020-06-24 15:51:18.496 INFO 17092 --- [ taskExecutor-4] c.l.u.i.demo.TinfoDemoScheduleTask : 测试fixedRate,线程名称:taskExecutor-4
  5. 2020-06-24 15:51:18.500 INFO 17092 --- [ taskExecutor-5] c.l.u.i.demo.TinfoDemoScheduleTask : 测试fixedDelay,线程名称:taskExecutor-5
  6. 2020-06-24 15:51:19.001 INFO 17092 --- [ taskExecutor-6] c.l.u.i.demo.TinfoDemoScheduleTask : 测试cron表达式,线程名称:taskExecutor-6
  7. 2020-06-24 15:51:19.496 INFO 17092 --- [ taskExecutor-7] c.l.u.i.demo.TinfoDemoScheduleTask : 测试fixedRate,线程名称:taskExecutor-7

非异步定时任务

启动定时任务

  1. import org.slf4j.Logger;
  2. import org.slf4j.LoggerFactory;
  3. import org.springframework.scheduling.annotation.Async;
  4. import org.springframework.scheduling.annotation.Scheduled;
  5. import org.springframework.stereotype.Component;
  6. @Component
  7. public class TinfoDemoScheduleTaskTwo {
  8. private static final Logger logger = LoggerFactory.getLogger(TinfoDemoScheduleTaskTwo.class);
  9. @Scheduled(cron = "0/1 * * * * *")
  10. public void scheduled() {
  11. logger.info("测试cron表达式,线程名称:{}", Thread.currentThread().getName());
  12. }
  13. @Scheduled(fixedRate = 1000)
  14. public void scheduledDemo1() {
  15. logger.info("测试fixedRate,线程名称:{}", Thread.currentThread().getName());
  16. }
  17. @Scheduled(fixedDelay = 1000)
  18. public void scheduledDemo2() {
  19. logger.info("测试fixedDelay,线程名称:{}", Thread.currentThread().getName());
  20. }
  21. }

Console

  1. 2020-06-24 16:05:32.277 INFO 9400 --- [ scheduling-1] c.l.u.i.demo.TinfoDemoScheduleTaskTwo : 测试fixedRate,线程名称:scheduling-1
  2. 2020-06-24 16:05:32.282 INFO 9400 --- [ scheduling-1] c.l.u.i.demo.TinfoDemoScheduleTaskTwo : 测试fixedDelay,线程名称:scheduling-1
  3. 2020-06-24 16:05:33.002 INFO 9400 --- [ scheduling-1] c.l.u.i.demo.TinfoDemoScheduleTaskTwo : 测试cron表达式,线程名称:scheduling-1
  4. 2020-06-24 16:05:33.276 INFO 9400 --- [ scheduling-1] c.l.u.i.demo.TinfoDemoScheduleTaskTwo : 测试fixedRate,线程名称:scheduling-1
  5. 2020-06-24 16:05:33.283 INFO 9400 --- [ scheduling-1] c.l.u.i.demo.TinfoDemoScheduleTaskTwo : 测试fixedDelay,线程名称:scheduling-1
  6. 2020-06-24 16:05:34.002 INFO 9400 --- [ scheduling-1] c.l.u.i.demo.TinfoDemoScheduleTaskTwo : 测试cron表达式,线程名称:scheduling-1
  7. 2020-06-24 16:05:34.277 INFO 9400 --- [ scheduling-1] c.l.u.i.demo.TinfoDemoScheduleTaskTwo : 测试fixedRate,线程名称:scheduling-1

总结


在项目中还是使用异步的比较好,就算一个出现问题,其他的还是能执行,但是如果使用非异步的,那么当出现一个死掉,那么其他的也就停止执行了。

END


chaohen:https://juejin.im/user/5ee9e1b951882565a762e2c5

搞定~