java注解@Scheduled开启多线程定时任务

在方法前加注解@Scheduled即可使该任务为定时调度任务,但是在实际部署环境运行时,发现日志的打印十分卡顿,甚至出现滞后,定时任务没有按时执行,但是在自己的开发机上运行就没有出现卡顿;附上cron表达式网站:在线Cron表达式生成器

后来了解到但是该定时调度任务默认是单线程的,如果有多个定时任务,则会单线程按顺序执行,在服务器的单核性能不足时很容易遇到瓶颈,遭遇卡顿,自己的开发机的单核性能较强,就不卡顿;

单线程执行会导致后面的定时任务需要等待前面的任务执行完毕,就无法定时执行;假如最后一个任务是每个小时的00分00秒开始,每5分钟执行一次,但是由于单线程的性能问题,原计划于05、10、15等分执行的任务变为了06、11、16分执行,如果该任务中需要获取当前的时间,就会获取到不符合设计逻辑的滞后的时间,所以改为多线程执行是必须的;

走弯路:

使用注解@Async:

在注解@Scheduled前再加一个注解@Async,启动多线程执行;单核性能问题得到了立竿见影的解决,但是同时发现bug,定时任务在写库时出现了重复写入的现象;分析完写入逻辑后,发现写入没有问题,唯一的可能就是线程太多了,同一个定时任务有多个线程在同时执行,写入时就会同时写入,出现重复;

分析:@Scheduled是一个定时任务,并不会结束,而是定时触发,@Async结合@Scheduled之后就会变成了每次执行定时任务时,就会开启一个新线程,但是老线程还在运行该定时任务,新老线程都在执行一样的任务,线程数会不断增加,直到达到线程池配置的上限后开始报错;这里的错误原理类似于嵌套了循环;

解决方案:将注解@Scheduled配置为多线程:

虽然注解@Scheduled默认是单线程的,但是可以通过写配置类将其改为多线程执行,不需要借助@Async来开启多线程;

配置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
public class ScheduledConfig {
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        //最大线程数
        taskScheduler.setPoolSize(30);
        return taskScheduler;
    }

}

使用注解@Scheduled时,在类名前加上注解@EnableScheduling即可。

改好后执行起来符合预期,没有出现问题;

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值