首页 > 其他分享 >定时任务cron表达式时间失效问题(未按表达式时间运行) 配置定时任务线程池或者同步解决

定时任务cron表达式时间失效问题(未按表达式时间运行) 配置定时任务线程池或者同步解决

时间:2022-08-16 11:45:25浏览次数:59  
标签:异步 cron 任务 线程 executor 定时 public 表达式

例如定时任务方法上的注解  cron表达式是这样会的:

@Async  //异步
@Scheduled(cron = "0 59 * * * ?")  //表达式  每小时的59分执行一次
@DataSource(DataSourceType.YK)  //自定义注解切库

出现的问题: 插入数据库的时间对应不上

是因为springboot默认给定时任务配置的线程池只有一个线程,当很多个定时任务都加了异步注解,没有配置线程池时,他们会因为只有一个线程出问题。

因为springboot的定时任务默认的线程池只有一个线程,就算加了异步,也不能使得一个任务结束下个任务才能开始,所以要配置一下或者重写定时任务的线程池,也可以将异步注解去掉,将异步注解去掉,springboot就会给定时任务配置一个固定的线程,不受干扰.

没有配置定时任务线程池时,默认用的是springboot分配给定时任务的线程池SimpleAsyncTaskExecutor,当一个服务定时任务过多时,会有问题比如你一个任务的周期是5秒,这5秒你要发送100条短信,用之前的固定的线程肯定没有问题,现在你改成多个线程。5秒如果你上个任务没有执行完成,那现在你任务的第二个周期到了还是会执行,如果没有控制可能会重复发

 

 

配置定时任务:

1、启动类

添加@EnableScheduling开启对定时任务的支持,@EnableAsync开启异步注解

2、编写定时任务类

@Component
@Slf4j
public class SaveDeviceRunTime

@Async
@Scheduled(cron = "0 59 * * * ?")
public void SaveDeviceRunTime()

 

添加@Async注解,表示该定时任务是异步执行的,因为上面线程池配置了名字,所以可以看到打印的日志是该线程池中的线程在执行任务,如果没有配置线程池的话会默认使用SimpleAsyncTaskExecutor,这个异步执行器每次都会开启一个子线程执行,性能消耗比较大,所以最好是自己配置线程池

如果没有配置异步注解的花,springboot就会分配固定的线程scheduling

 

 


所以可以在启动类上配置线程池或者建一个线程池配置类
@Bean
    public Executor executor1() {

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setThreadNamePrefix("test-schedule1-");
        executor.setMaxPoolSize(20);
        executor.setCorePoolSize(15);
        executor.setQueueCapacity(10);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

or:

@Configuration
@EnableAsync
public class ExecutorConfig {
    @Bean
    public Executor executor1() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setThreadNamePrefix("test-schedule1-");
        executor.setMaxPoolSize(20);
        executor.setCorePoolSize(15);
        executor.setQueueCapacity(10);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
    
    @Bean
    public Executor executor2() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setThreadNamePrefix("test-schedule2-");
        executor.setMaxPoolSize(20);
        executor.setCorePoolSize(15);
        executor.setQueueCapacity(10);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

}

 

测试如下:

@Component
@Slf4j
@EnableScheduling
public class test {

    @Async("executor1")  //指定线程池bean的名字  为什么是这个名字,可以自行学习下spring 关于bean的生命周期和创建过程
    @Scheduled(cron = "0 0/1 * * * ?")
    public void test() {
        System.out.println(Thread.currentThread().getName());
    }
}
@Component
@Slf4j
@EnableScheduling
public class test1 {

    @Async
    @Scheduled(cron = "0 0/1 * * * ?")
    public void test1() {
        System.out.println(Thread.currentThread().getName() + "-------");
    }
}

结果: 可以看到未指定线程池,默认就会使用的是SimpleAsyncTaskExecutor

也可以选择不配置异步,用同步,那么springboot就会给它分配固定的线程,不会被干扰

 

 



标签:异步,cron,任务,线程,executor,定时,public,表达式
From: https://www.cnblogs.com/gujiajie/p/16591036.html

相关文章

  • 【快应用】通知消息定时提醒
    【现象描述】当用户使用快应用时,定时给用户发送提醒,省去了去桌面找该快应用的图标或者去快应用中心寻找该应用的过程。在onHide中添加定时器,当用户离开应用时定时发送通......
  • vue js 计时器setInterval(),setTimeout() 循环调用,定时调用
    setInterval():他就是每隔多少秒或毫秒调用(循环的调用)。setTimeout():他就是过了多少秒或毫秒调用(调用一次)。//过500毫秒调用setTimeout(()=>{//方法区},500);//......
  • 正则表达式匹配“\xa0”的问题
    【问题】正则表达式匹配国际手机号:+xxxxxxxxxxxxx格式,结果报错【原因】\xao0空格【方法一】换成键盘上的空格,让前端传的参数改一下 结果是可以的,但是前端既然会......
  • 10--栈计算器(补充:前缀、中缀、后缀表达式规则;逆波兰表达式计算器)
    一、前缀表达式【波兰表达式】:前缀表达式也称为波兰表达式,其特点是运算符位于操作数之前举例说明:(3+4)*5-6对应的前缀表达式就是:-*+3456前缀表达式的计算机求值......
  • 7、定时进行数据批处理任务
    一、StopWatch时间控制类:StopWatch是spring工具包org.springframework.util下的一个工具类,主要用于计算同步单线程执行时间。1、StopWatch优缺点:优点:(1)、spring自带工......
  • 2022-08-12第二小组 张晟源(正则表达式)
    JAVA(正则表达式)元字符. :匹配处了换行符之外的任意字符\w:匹配字符或数字或下划线或汉字\s:空格\d:匹配数字\b:匹配单词的开始和结束^:匹配字符串的开始$:匹配字符串的......
  • Failed to list *v1.CronJob: the server could not find the requested resource
    基础环境kubectlversionClientVersion:version.Info{Major:"1",Minor:"20",GitVersion:"v1.20.7",GitCommit:"132a687512d7fb058d0f5890f07d4121b3f0a2e2",GitTre......
  • javascript关于正则表达式
    概述正则表达式是用于字符串匹配的(四个支持正则的方法search查找下标macth查找数组split切割 replace替换)1.正则表达式对象声明1.1new关键词声明varre......
  • 运算符及表达式
    运算符及表达式//()前面不能直接写++console.log(++(a++));//()不能和++一起使用​​//字符串和数值进行比较(字符串会自动转换为数值)console.log(1>2);//falseconsole.lo......
  • day 13 正则表达式
    正则表达式正则表达式的概述正则表达式(RegularExpression)是一个描述字符模式的对象,用于对字符串进行匹配,一般用在有规律的字符串匹配中;常用于表单验证以及相关的......