学习springBoot(12)定时任务

传统定时任务实现的几种方式:java

Timer:这是java自带的java.util.Timer类,这个类容许你调度一个java.util.TimerTask任务。使用这种方式可让你的程序按照某一个频度执行,但不能在指定时间运行。通常用的较少。

ScheduledExecutorService:也jdk自带的一个类;是基于线程池设计的定时任务类,每一个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。

Spring Task:Spring3.0之后自带的task,能够将它当作一个轻量级的Quartz,并且使用起来比Quartz简单许多。

Quartz:这是一个功能比较强大的的调度器,可让你的程序在指定时间执行,也能够按照某一个频度执行,配置起来稍显复杂。
复制代码

在SpringBoot项目中,咱们能够很简单的使用注解(@Scheduled)来实现定时任务express

首先了解一下@Scheduled这个注解bash

@Scheduled接受两种定时的设置:

一种是cornexpression。

一种是Rate/Delay表达式(毫秒值):

    @Scheduled(fixedRate = 6000):上一次开始执行时间点后每隔6秒执行一次。

    @Scheduled(fixedDelay = 6000):上一次执行完毕时间点以后6秒再执行。

    @Scheduled(initialDelay=1000, fixedRate=6000):第一次延迟1秒后执行,以后按fixedRate的规则每6秒执行一次。


注:

*表示全部值,在分钟里表示每一分钟触发。在小时,日期,月份等里面表示每一小时,每一日,每一月。

?表示不指定值。表示不关心当前位置设置的值。 好比不关心是周几,则周的位置填写?。  主要是因为日期跟周是有重复的因此二者必须有一者设置为?

- 表示区间。小时设置为10-12表示10,11,12点均会触发。

,表示多个值。 小时设置成10,12表示10点和12点会触发。

/ 表示递增触发。 5/15表示从第5秒开始,每隔15秒触发。

L 表示最后的意思。 日上表示最后一天。星期上表示星期六或7。 L前加数据,表示该数据的最后一个。

星期上设置6L表示最后一个星期五。  6表示星期五

W表示离指定日期最近的工做日触发。15W离该月15号最近的工做日触发。

#表示每个月的第几个周几。 6#3表示该月的第三个周五。

 

示例:
"0 0 12 * * ?" 天天中午12点触发 
"0 15 10 ? * *" 天天上午10:15触发 
"0 15 10 * * ?" 天天上午10:15触发 
"0 15 10 * * ? *" 天天上午10:15触发 
"0 15 10 * * ? 2005" 2005年的天天上午10:15触发 
"0 * 14 * * ?" 在天天下午2点到下午2:59期间的每1分钟触发 
"0 0/5 14 * * ?" 在天天下午2点到下午2:55期间的每5分钟触发 
"0 0/5 14,18 * * ?" 在天天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 
"0 0-5 14 * * ?" 在天天下午2点到下午2:05期间的每1分钟触发 
"0 10,44 14 ? 3 WED" 每一年三月的星期三的下午2:10和2:44触发 
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 
"0 15 10 15 * ?" 每个月15日上午10:15触发 
"0 15 10 L * ?" 每个月最后一日的上午10:15触发 
"0 15 10 ? * 6L" 每个月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每个月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6#3" 每个月的第三个星期五上午10:15触发 
天天早上6点     0 6 * * *     每两个小时     0 */2 * * * 
晚上11点到早上8点之间每两个小时,早上八点    0 23-7/2,8 * * * 
每月的4号和每一个礼拜的礼拜一到礼拜三的早上11点     0 11 4 * 1-3 
1月1日早上4点     0 4 1 1 *
 
复制代码

在线Cron表达式生成器: cron.qqe2.com/多线程

在主类上使用@EnableScheduling注解开启对定时任务的支持并发

@Component
public class ScheduledTest {
    private static Logger logger = LoggerFactory.getLogger(ScheduledTest.class);

    @Scheduled(cron = "0/5 * * * * *")
    public void scheduled(){
        logger.info("=====>>>>>cron执行-{}",DateUtils.getCurrentDateMillTime());
    }
    @Scheduled(fixedRate = 5000)
    public void scheduled1() {
        logger.info("=====>>>>>fixedRate执行-{}", DateUtils.getCurrentDateMillTime());
    }
    @Scheduled(fixedDelay = 5000)
    public void scheduled2() {
        logger.info("=====>>>>>fixedDelay执行-{}",DateUtils.getCurrentDateMillTime());
    }
}


复制代码

重启项目发现后台已经有任务在定时执行,时间间隔5秒异步

三个定时任务都已经执行,而且使同一个线程中串行执行,若是只有一个定时任务,这样作确定没问题,当定时任务增多,若是一个任务卡死,会致使其余任务也没法执行,这时候就要使用多线程执行ui

建立AsyncConfig类:spa

@Configuration
@EnableAsync //开启异步事件的支持
public class AsyncConfig {
    @Value("${corePoolSize}")
    private int corePoolSize;

    @Value("${maxPoolSize}")
    private int maxPoolSize;

    @Value("${queueCapacity}")
    private int queueCapacity;

    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.initialize();
        return executor;
    }
}
复制代码

相应配置文件:线程

#定时任务配置
corePoolSize: 10
maxPoolSize: 200
queueCapacity: 10
复制代码

最后,在定时任务的类或者方法上添加@Async 。最后重启项目,每个任务都是在不一样的线程中,相互之间不影响设计

相关文章
相关标签/搜索