Spring Boot 多个定时器冲突问题的解决方法

目录
  • 战术分析
  • 使用场景
  • 问题场景重现
    • 添加注解
    • 配置类

战术分析

上次的博客疏忽了定时器的一个大重点…

实际开发项目中一定不止一个定时器,很多场景都需要用到,而多个定时器带来的问题 : 就是如何避免多个定时器的互相冲突。

推荐一个 Spring Boot 基础教程及实战示例:https://github.com/javastacks/spring-boot-best-practice

使用场景

我们的订单服务,一般会有一个待支付订单,而这个待支付订单是有时间限制的,比如阿里巴巴的订单是五天,淘宝订单是一天,拼多多订单是一天,美团订单是15分钟…

基金系统中,如何同时更新多个存储分区中的基金信息…

总的来说,实际开发中定时器需要解决多个定时器同时并发的问题,也要解决定时器之间的冲突问题

问题不大,说到并发那就离不开多线程了…慢慢看看就懂了

问题场景重现

我们清晰的看到执行结果都是scheduling-1

就此可以判定,Springboot定时器默认的是单线程的

但是问题就来了,如果在线程争夺资源后,某个线程需要比较长时间才能执行完,那其他的定时器怎么办,都只能进入等待状态,时间越久,累计等待的定时器越多,这就容易引起雪崩…

其实只需要添加一个配置类然后加注解就可以解决问题了

添加注解

具体代码如下 :

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class SchedulerTaskController {
    private Logger logger= LoggerFactory.getLogger(SchedulerTaskController.class);
    private static final SimpleDateFormat dateFormat=new SimpleDateFormat("HH:mm:ss");
    private int count=0;
    @Scheduled(cron="*/6 * * * * ?")
    @Async("threadPoolTaskExecutor")
    public void process(){
        logger.info("英文:this is scheduler task runing "+(count++));
    }
    @Scheduled(fixedRate = 6000)
    @Async("threadPoolTaskExecutor")
    public void currentTime(){
        logger.info("中文:现在时间"+dateFormat.format(new Date()));
    }
}

配置类

具体代码如下 :

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**使用多线程的时候,往往需要创建Thread类,或者实现Runnable接口,如果要使用到线程池,我们还需要来创建Executors,
 * 在使用spring中,已经给我们做了很好的支持。只要要@EnableAsync就可以使用多线程
 * 通过spring给我们提供的ThreadPoolTaskExecutor就可以使用线程池。*/
//@Configuration 表示该类是一个配置类
@Configuration
@EnableAsync
//所有的定时任务都放在一个线程池中,定时任务启动时使用不同都线程。
public class TaskScheduleConfig {
    private static final int corePoolSize = 10;       		// 默认线程数
    private static final int maxPoolSize = 100;			    // 最大线程数
    private static final int keepAliveTime = 10;			// 允许线程空闲时间(单位:默认为秒),十秒后就把线程关闭
    private static final int queueCapacity = 200;			// 缓冲队列数
    private static final String threadNamePrefix = "it-is-threaddemo-"; // 线程池名前缀
    @Bean("threadPoolTaskExecutor") // bean的名称,默认为首字母小写的方法名
    public ThreadPoolTaskExecutor getDemoThread(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(keepAliveTime);
        executor.setKeepAliveSeconds(queueCapacity);
        executor.setThreadNamePrefix(threadNamePrefix);
        //线程池拒绝任务的处理策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //初始化
        executor.initialize();

        return executor;
    }
}

然后我们可以很清晰地看到:

如上,也就解决了用多线程解决Springboot多定时器冲突的问题

到此这篇关于Spring Boot 多个定时器冲突问题的解决方法的文章就介绍到这了,更多相关Spring Boot 定时器冲突内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot集成ElaticJob定时器的实现代码

    本文介绍了SpringBoot集成ElaticJob定时器的实现代码,分享给大家,具体如下: POM文件配置 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sch

  • Springboot集成定时器和多线程异步处理操作

    需求:用@schedule标签进行定时处理逻辑,由于业务处理速度慢,需要每次执行逻辑放在不同的线程里异步执行 springboot集成多线程异步,直接上配置: /** * 线程池异步配置 */ @Configuration @EnableAsync public class ThreadExecutorConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskE

  • 使用springboot时,解决@Scheduled定时器遇到的问题

    目录 @Scheduled定时器遇到的问题 下面说一下@Scheduled 注解的几个参数 一.可以通过配置文件配置进来的 二.不可通过配置文件配置的 (作用相同) 定时任务@Scheduled使用的那些坑 一.使用的那些坑? 1.单线程 2.@Async和@EnableAsync 二.使用多线程 小结一下 @Scheduled定时器遇到的问题 @Scheduled 这个注解确实给我们带了很大的方便,我们只要加上该注解,并且根据需求设置好就可以使用定时任务了. 但是,我们需要注意的是,@Sche

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

    目录 使用定时器@Scheduled不管用 多个@Scheduled定时器不执行 解决方法 使用定时器@Scheduled不管用 如果是一开始就不能用就是没写@EnableScheduling注解,如果是用着用着不管用了 是因为@Scheduled是单线程,有定时器在工作或者没有运行完毕,所以造成了线程堵塞所以导致下一个定时器不能运行增加一个方法类 package com.llt; import org.springframework.boot.autoconfigure.batch.Batch

  • SpringBoot 动态定时器的使用方法

    SpringBoot使用定时器使用方法添加@Scheduled注解 设计cron参数即可 package com.clsystem.Comm; import org.springframework.scheduling.annotation.Scheduled; /** * Created by pudding on 2017-11-10.(打卡记录定时任务) */ @Component public class ClockTiming { /** * 定时器 */ @Scheduled(cro

  • SpringBoot开发实战系列之定时器

    前言 定时器功能在项目里面往往会用到,比如定时发送邮件.定时释放数据库资源:这里记录一下springboot对定时器的支持的简单实例 cron表达式 开始之前要先介绍一下cron表达式,这里当一下百度百科搬运工: Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: Seconds Minutes Hours DayofMonth Month DayofWeek Year或 Seconds Minutes Hours Dayof

  • Spring Boot 多个定时器冲突问题的解决方法

    目录 战术分析 使用场景 问题场景重现 添加注解 配置类 战术分析 上次的博客疏忽了定时器的一个大重点… 实际开发项目中一定不止一个定时器,很多场景都需要用到,而多个定时器带来的问题 : 就是如何避免多个定时器的互相冲突. 推荐一个 Spring Boot 基础教程及实战示例:https://github.com/javastacks/spring-boot-best-practice 使用场景 我们的订单服务,一般会有一个待支付订单,而这个待支付订单是有时间限制的,比如阿里巴巴的订单是五天,淘

  • Spring Boot中自动化配置的利弊以及解决方法

    本文主要给大家介绍了关于Spring Boot自动化配置的利弊及解决方法的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: Spring Boot中的双刃剑:自动化配置 在之前的文章中,我们通过各种功能性示例体验了Spring Boot的自动化配置给我们所带来的超便利的新开发方式.但是,在一些情况下Spring Boot的自动化配置也会给我们惹来不少的麻烦,比如这些场景: 项目依赖复杂的情况下,由于依赖方的依赖组织不够严格,可能引入了一些实际我们不需要的依赖,从而导致我们

  • Spring Boot接收单个String入参的解决方法

    前言 接受参数是我们在日常开发中经常会遇到的一个需求,下面这篇文章主要给大家介绍了关于Spring Boot接收单个String入参之解决方案的相关内容,下面话不多说了,来一起看看详细的介绍吧 场景: 在做接口时,有的时候,接口入参只需要一个参数,如果将一个参数封装成一个对象很麻烦,故有了以下方式: 思路: spring自带的参数解析器貌似是不具备这个能力的,所有自定义 方式方法: 1.定义一个注解 @Target(ElementType.PARAMETER) @Retention(Retent

  • Spring Boot多个定时任务阻塞问题的解决方法

    目录 前言 1.重写SchedulingConfigurer#configureTasks() 2.通过配置开启 3.结合@Async 总结 前言 今天这篇文章介绍一下Spring Boot 中 如何开启多线程定时任务? 为什么Spring Boot 定时任务是单线程的? 想要解释为什么,一定要从源码入手,直接从@EnableScheduling这个注解入手,找到了这个ScheduledTaskRegistrar类,其中有一段代码如下: protected void scheduleTasks(

  • Spring Boot security 默认拦截静态资源的解决方法

    Spring Boot security 会默认登陆之前拦截全部css, js,img等动态资源,导致我们的公开主页在登陆之前很丑陋 像这样: 网上很多解决办法都过时了比如还在使用WebSecurityConfigurerAdapte,antMatchers public class SecurityConfigurer extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web)

  • 教你在Spring Boot微服务中集成gRPC通讯的方法

    一.首先声明gRPC接口 这里引入的是最新的gRpc-core 1.37版本, 采用的grcp-spring-boot-starter封装的版本进行实现,github地址: https://github.com/yidongnan/grpc-spring-boot-starter 要实现gRpc通讯, 先定义接口以及入参出参信息 syntax = "proto3"; option java_multiple_files = true; option java_package = &qu

  • Spring boot 跳转到jsp页面的实现方法

    本人正在学习Spring boot,搜索了很多关于Spring boot 跳转到jsp页面的实现方法介绍,下面我来记录一下,有需要了解的朋友可参考.希望此文章对各位有所帮助. @Controller注解 1.application.properties文件中配置 # 配置jsp文件的位置,默认位置为:src/main/webapp spring.mvc.view.prefix=/pages/ # 配置jsp文件的后缀 spring.mvc.view.suffix=.jsp 2.Controlle

  • Spring Boot下如何自定义Repository中的DAO方法

     环境配置介绍 jdk 1.8, spring Boot 1.5.3.RELEASE, MySQL, Spring Data, JPA 问题描述 Spring Data提供了一套简单易用的DAO层抽象与封装,覆盖的CURD的基本功能,但是在诸多的情况下,需要用户自定义DAO的实现方法,来实现更为复杂和精细的数据库访问操作,该如何来解决这个问题? 目标描述 这里我们以自定义testAA的方法为例,来介绍如何实现自定义的DAO方法扩展. 数据库表的定义 我们这里定义了一个非常简单的mycity表,来

  • Spring Boot 与 Kotlin 使用Redis数据库的配置方法

    Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, Elasticsearch, Solr和Cassandra. 使用Redis Redis是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型. Key-Value 数据库. Redis官网 Redis中文社区 引入依赖 Spring Boot提供的数据访问框架Spring Data Redis基于Jedi

  • Spring Boot 配置 IDEA和DevTools 热部署的方法

    MAVEN 配置 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/

随机推荐