springboot使用定时器@Scheduled不管用的解决

 更新时间:2021年12月28日 17:07:44   作者:悠_ran  
这篇文章主要介绍了springboot使用定时器@Scheduled不管用的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

使用定时器@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());
 //业务内容
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringData JPA审计功能(@CreatedDate与@LastModifiedDate)实现

    SpringData JPA审计功能(@CreatedDate与@LastModifiedDate)实现

    Spring Data JPA的审计功能提供了一种强大而灵活的机制,用于自动跟踪实体的创建和修改信息,通过使用@CreatedDate和@LastModifiedDate注解,开发者可以轻松地实现时间审计,感兴趣的可以了解一下
    2025-04-04
  • Java类中this关键字与static关键字的用法解析

    Java类中this关键字与static关键字的用法解析

    这篇文章主要介绍了Java类中this关键字与static关键字的用法解析,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • IDEA 使用mybatis插件Free Mybatis plugin的步骤(推荐)

    IDEA 使用mybatis插件Free Mybatis plugin的步骤(推荐)

    这篇文章主要介绍了IDEA 使用mybatis插件Free Mybatis plugin的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • Java中filter用法完整代码示例

    Java中filter用法完整代码示例

    这篇文章主要介绍了Java中filter用法完整代码示例,分享了浏览器不缓存页面的过滤器,检测用户是否登陆的过滤器等相关实例,小编觉得还是挺不错的,这里分享给大家,需要的朋友可以参考下
    2018-01-01
  • Java自定义函数调用方法解析

    Java自定义函数调用方法解析

    这篇文章主要介绍了java自定义函数调用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • java中将科学计数法转换普通计数法的简单方法

    java中将科学计数法转换普通计数法的简单方法

    下面小编就为大家带来一篇java中将科学计数法转换普通计数法的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • Java正则判断日期格式是否正确的方法示例

    Java正则判断日期格式是否正确的方法示例

    这篇文章主要介绍了Java正则判断日期格式是否正确的方法,结合实例形式分析了Java针对日期字符串正则判断的相关操作技巧,需要的朋友可以参考下
    2017-03-03
  • java执行shell并获取shell输出日志方式

    java执行shell并获取shell输出日志方式

    这篇文章主要介绍了java执行shell并获取shell输出日志方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • Java中断异常的正确处理方法

    Java中断异常的正确处理方法

    这篇文章主要给大家介绍了关于Java中断异常的正确处理方法,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • Java Map接口及其实现类原理解析

    Java Map接口及其实现类原理解析

    这篇文章主要介绍了Java Map接口及其实现类原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03

最新评论