springboot使用定时器@Scheduled不管用的解决
程序员文章站
2022-03-08 15:33:46
目录使用定时器@scheduled不管用多个@scheduled定时器不执行解决方法使用定时器@scheduled不管用如果是一开始就不能用就是没写@enablescheduling注解,如果是用着用...
使用定时器@scheduled不管用
如果是一开始就不能用就是没写@enablescheduling注解,如果是用着用着不管用了 是因为@scheduled是单线程,有定时器在工作或者没有运行完毕,所以造成了线程堵塞所以导致下一个定时器不能运行增加一个方法类
package com.llt; import org.springframework.boot.autoconfigure.batch.batchproperties; import org.springframework.context.annotation.configuration; import org.springframework.scheduling.annotation.scheduled; import org.springframework.scheduling.annotation.schedulingconfigurer; import org.springframework.scheduling.config.scheduledtaskregistrar; import java.lang.reflect.method; import java.util.concurrent.executors; @configuration public class scheduleconfig implements schedulingconfigurer { @override public void configuretasks(scheduledtaskregistrar taskregistrar) { method[] methods = batchproperties.job.class.getmethods(); int defaultpoolsize = 3; int corepoolsize = 0; if (methods != null && methods.length > 0) { for (method method : methods) { scheduled annotation = method.getannotation(scheduled.class); if (annotation != null) { corepoolsize++; } } if (defaultpoolsize > corepoolsize) corepoolsize = defaultpoolsize; } taskregistrar.setscheduler(executors.newscheduledthreadpool(corepoolsize)); } }
就好了!
多个@scheduled定时器不执行
最近项目中经常有用到@scheduled注解,在内测时由于数据量小(没有进行压力测)所以每个线程执行都很快,但线上后发现部分功能无法使用,最后定位是部分的定时器没有执行,后查阅资料和springboot源码后
scheduledtaskregistrar在启动时,如果没有指定线程池的大小,默认会创建核心线程数为1的默认线程池,故而当项目中出现多个@scheduled线程时,只能一个个的执行,从而导致个别线程执行时间过长(或长期执行)时,其他定时器不能按照指定的规则进行执行。
解决方法
1.在项目初始化时指定其执行线程池的大小
import org.springframework.boot.autoconfigure.batch.batchproperties; import org.springframework.context.annotation.configuration; import org.springframework.scheduling.annotation.scheduled; import org.springframework.scheduling.annotation.schedulingconfigurer; import org.springframework.scheduling.config.scheduledtaskregistrar; import java.lang.reflect.method; import java.util.arrays; import java.util.objects; import java.util.concurrent.scheduledthreadpoolexecutor; import java.util.concurrent.atomic.atomicinteger; /** * 程序名 : scheduledtaskconfiguration * 建立日期: 2021-02-23 9:33 * 模块 : scheduled任务线程池设置 * 描述 : 读取项目中使用了@scheduled注解的方法,默认所有方法在项目创建时都需要按照设定的规则执行 * 备注 : //todo * <p> * 修改历史 * 序号 日期 修改人 修改原因 */ @configuration public class scheduledtaskconfiguration implements schedulingconfigurer { @override public void configuretasks(scheduledtaskregistrar taskregistrar) { method[] methods = batchproperties.job.class.getmethods(); final atomicinteger corepoolsize = new atomicinteger(); if (objects.nonnull(methods) && methods.length > 0) { arrays.stream(methods).foreach(method -> { final scheduled annotation = method.getannotation(scheduled.class); if (objects.nonnull(annotation)) { corepoolsize.incrementandget(); } }); } scheduledthreadpoolexecutor executor = new scheduledthreadpoolexecutor(corepoolsize.get()); taskregistrar.setscheduler(executor); } }
2.将定时器设置为异步线程
/** 异步线程 定时器延迟1秒启动,每距上一次执行完成后间隔3秒执行一次 */ @async("taskexecutor") @scheduled(initialdelay = 1000l, fixeddelay = 3000l) public void test(){ system.out.println("---"+system.currenttimemillis()); //业务内容 }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
-
springboot 高版本后继续使用log4j的完美解决方法
-
使用swoole 定时器变更超时未支付订单状态的解决方案
-
倒计时cocos定时器schude使用的过程中 帧率浮动较大导致执行时机不准确的问题解决
-
Springboot mybatis plus druid多数据源解决方案 dynamic-datasource的使用详解
-
SpringBoot 定时器注解版的使用@Scheduled(cron = “0 0 0 * * * “)
-
springboot+shiro中使用 @RequiresPermissions和@RequiresRoles无效的解决方法
-
springboot使用CommandLineRunner解决项目启动时初始化资源的操作
-
SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题的解决方法
-
SpringBoot使用AOP,内部方法失效的解决方案
-
idea快捷键不管用了怎么办?intellij idea快捷键无法正常使用的解决方法