Spring定时任务延时触发分析与解决:从单线程阻塞到多线程并发

滴滴后端高频面试题复盘:从JVM原理到分布式架构的考点全解 后端面试中,Java基础与并发编程是技术深度的第一道门槛,而分布式系统设计与高可用架构则是决定面试上限的分水岭。在备战大厂后端岗位时,理解线程池参数、索引优化原理、缓存一致性等核心概念,远比记忆零散题目更有价值。掌握JVM垃圾回收机制、秒杀场景下的限流降级策略、消息队列削峰填谷的应用,是应对订单与支付等复杂业务场景的关键。结合真实项目中的性能调优与异常排查经验,能够系统构建从并发编程到微服务治理的知识体系。梳理高并发场景下的工程实践与原理,正是冲刺滴滴及同类互联网公司后端岗位的有效路径。 阅读详情

问题背景:神秘的执行延迟

在近期维护的项目中,发现两个设置在同一时间(每天00:10)执行的定时任务出现了意外行为

// 任务A:数据归档任务
@Scheduled(cron = "0 10 0 * * ?")
public void saticschedule() {
    // 数据归档操作
}

// 任务B:日志分区维护任务
@Scheduled(cron = "0 10 0 * * ?")
public void cycleTask() {
    // 日志分区维护
}

通过日志排查发现,虽然两个任务配置了相同的触发时间,但任务B总是比任务A晚执行,且延迟时间恰好接近任务A的执行时长。这种看似"排队"的现象引发了我们的深入排查。

问题根源:Spring的定时任务单线程模型

通过源码分析和日志跟踪,我们定位到根本原因在于Spring默认的单线程任务执行机制:

1.单线程任务调度器

Spring的@Scheduled注解底层使用SingleThreadScheduledExecutor,这意味着:

  • 所有定时任务共享同一线程
  • 任务按注册顺序排队执行
  • 前序任务会阻塞后续任务

2.任务注册顺序决定执行顺序

在我们的项目中:

java
@Configuration
public class SaticScheduleTask { /* 先注册 */ } 

@Configuration
public class ScheduledTask { /* 后注册 */ }

由于SaticScheduleTask类定义在前,它的任务会先进入执行队列

3.耗时操作加剧阻塞

任务A中的数据库归档操作需要较长时间执行,导致任务B即使到达触发时间也必须等待


解决方案:多线程并发执行

方案一:自定义线程池

通过实现SchedulingConfigurer接口配置线程池:

@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {
    
    @Override
    public void configureTasks(ScheduledTaskRegistrar registrar) {
        ThreadPoolTaskScheduler threadPool = new ThreadPoolTaskScheduler();
        threadPool.setPoolSize(5); // 根据任务数量调整
        threadPool.setThreadNamePrefix("sched-");
        threadPool.setAwaitTerminationSeconds(60);
        threadPool.setWaitForTasksToCompleteOnShutdown(true);
        threadPool.initialize();
        
        registrar.setTaskScheduler(threadPool);
    }
}

方案二:异步执行

结合@Async实现异步任务:

@Configuration
@EnableAsync
public class AsyncConfig {
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(3);
        executor.setMaxPoolSize(5);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("AsyncTask-");
        executor.initialize();
        return executor;
    }
}

// 在定时任务上添加注解
@Async
@Scheduled(cron = "0 10 0 * * ?")
public void cycleTask() { ... }
钉钉Java面经及参考答案 TCP 三次握手建立连接的核心目标是双向确认双方发送、接收能力,同步通信序列号,协商初始窗口大小,防止历史过期连接报文干扰新连接。第一次握手,客户端主动向服务端发送 SYN 报文,携带客户端随机生成的初始序列号 ISN,客户端状态变更为 SYN_SENT,目的是告知服务端客户端具备发送数据的能力。第二次握手,服务端收到 SYN 报文后,回复 SYN+ACK 报文,其中 ACK 确认号为客户端 ISN+1,同时携带服务端自身随机初始序列号,服务端进入 SYN_RCVD 状态,代表服务端确认收到客户端报文,且自 阅读详情

相关推荐

springboot执行延时任务之DelayQueue的使用详解

DelayQueue是一个无界阻塞队列,只有在延迟期满时,才能从中提取元素。这篇文章主要介绍了springboot执行延时任务-DelayQueue的使用,需要的朋友可以参考下

定时/延时任务-Spring定时任务的两种实现方式

关于 Spring,其实提供了两种方式实现定时任务,一种是注解,还有一种就是接口了,下面我就会讲一下这两种方式的用法,在下一篇文章中我们会继续深入 Spring 源码,去讲解 Spring 里面的定时任务到底是怎么实现的。不过其实核心思想都是一样的,就算自己去实现了,固定速率和固定延时的核心都是一样的,只是实现上会不一样,可以对比下 ScheduledThreadPoolExecutor 和 Timer 的实现。结果输出如下,固定延时就是要确保本次任务执行的时间距离上一次任务执行完成的时间相差 5s。

Jwasx的博客 1422

F5高可用HA配置详情

F5 HA详细配置

weixin_45843944的博客 3022

【应用篇】---史上最全的延迟任务实现方式汇总!

不用谢我,送人玫瑰,手有余香。相信接下来的内容一定不会让你失望,因为它将是目前市面上最好的关于“延迟任务”的文章,这也一直是我写作追求的目标,让我的每一篇文章都比市面上的好那么一点点。 好了,话不多说,直接进入今天的主题,本文的主要内容如下图所示: 什么是延迟任务? 顾明思议,我们把需要延迟执行的任务叫做延迟任务。 延迟任务的使用场景有以下这些: 红包 24 小时未被查收,需要延...

没有伞的孩子必须努力奔跑!—小林 1397

岭回归的MATLAB步骤

MATLAB 实现框架,它涵盖了从数据导入到岭回归的步骤,包括计算共线性、使用 MAE、MSE、R²、MAPE 进行评价,以及绘制相应的可视化图表。

subject625Ruben的博客 1089

棋牌App逆向工程实战:透视风险分析与反作弊加固思路

在移动应用安全领域,逆向工程是一项关键的攻防技术,它通过静态分析、动态调试与协议抓包等手段,深入还原客户端真实逻辑。这项技术的核心原理,是从已编译的安装包中提取数据流,验证服务端下发的信息是否超出了客户端应有的可见范围。从技术价值看,安全测试人员可以借此定位协议层、内存层与缓存层的潜在风险,为反作弊体系提供精准的加固建议。在棋牌类App等实时对局场景中,逆向工程常被用于排查牌局信息泄露类隐患,而合规授权与测试环境是开展此类研究的必要前提。本文结合一次棋牌App的安全评估实践,梳理了从环境准备到数据流还原的完

weixin_29326909的博客 173

SpringCloud微服务项目实战 - 6.延迟任务

基于SpringCloud框架的微服务项目,新闻项目,,该项目是新闻头条的新闻资讯类项目; 平台涵盖 用户移动端App、媒体人发布文章的后台系统、后台管理系统; 技术栈全面,包括用户层、CDN(HTML、CSS、JSON、Video...)、LB(Nginx)、视图层(Vue、WEEX、Echarts)、网关(SpringCloud Gateway)、服务层(中间件、微服务、Nacos、云计算)、数据层(Mysql、MongoDB、Redis、中间件、OSS)

yuan 1099

告别TI官网迷路!手把手教你用C2000Ware为TMS320F28027搭建Proteus仿真工程模板

本文详细指导如何使用C2000Ware为TMS320F28027搭建Proteus仿真工程模板,帮助DSP开发者快速上手。从资源获取、工程目录设计到关键文件配置,再到CCS与Proteus的联调技巧,全面解析仿真工程搭建的每个步骤,特别适合初学者和工程师参考。

weixin_42715608的博客 472

延时任务的四种实现方式

而通过 JDK 实现延迟任务我们能想到的关键词是:DelayQueue、ScheduledExecutorService,而第三方提供的延迟任务执行方法就有很多了,例如:Redis、Netty、MQ 等手段。并且在Redis中,有很多默认的channel,只不过向这些channel发送消息的生产者不是我们写的代码,而是Redis本身。如果专门开启一个 MQ 中间件来执行延迟任务,就有点杀鸡用宰牛刀般的奢侈了,不过已经有了 MQ 环境的话,用它来实现延迟任务的话,还是可取的。

提供各种学习资源及帮助 9039

QT实现HTTP文件(夹)下载的完整流程与实战技巧

本文详细介绍了使用QT框架实现HTTP文件和文件夹下载的完整流程与实战技巧。通过QNetworkAccessManager等核心类,讲解了从单文件下载、大文件处理、进度显示、暂停/取消功能,到复杂的文件夹下载策略。文章重点剖析了断点续传、错误处理与网络健壮性等关键问题,为C++桌面应用集成稳定高效的下载功能提供了专业指导。

weixin_29239279的博客 277

Postman账号

Postman账号一、为什么要注册一个Postm账号二、如何注册Postman账号三、登录账号四、切换账号五、找回账号密码 一、为什么要注册一个Postm账号 注册Postman账号是免费的。当注册并登录一个Postman账号后,用户可以获得一下权限。 (1)同步和备份历史、集合、环境和预置头。 (2)可以轻松处理来自不同机器的多个Postman实例‘ (3)创建集合链接发送给其他开发人员。 当然,不注册也可以使用Postman。 二、如何注册Postman账号 (1)下载、安装Postman应用程序。 (

精益求精,永无止境,永远在路上! 6772

SpringBoot 异步延时任务

这个方法会在Spring容器启动后,所有Bean都已经被创建和初始化之后被调用。这个方法的参数是一个字符串数组,通常包含命令行参数,但是你可以根据需要忽略这个参数。在 run 方法中启用线程循环从队列中获取数据,获取不到就阻塞线程,直到有数据为止。异步延时任务在日常工作中是比较常见的。定义一个静态变量DelayQueue,用于保存延时任务。延迟队列是 jdk1.5 提供的,核心是优先级队列。要求队列中的元素必须实现。

MichaelZ的博客 1579

【MERRA-2数据集】M2I1NXASM (5.12.4) 和 M2I1NXINT (5.12.4)概述

M2I1NXASM (5.12.4) 和 M2I1NXINT (5.12.4)概述

WW、forever的博客 680

7个Java定时任务调度框架替代方案与性能优化实战指南

Java定时任务调度是后端开发中不可或缺的关键组件,用于处理周期性任务、延时任务等场景。GitHub加速计划中的RedSpider社区原创Java多线程系列文章,深入剖析了各类调度框架的实现原理与最佳实践。本文将为你系统梳理主流替代方案,提供可落地的性能优化策略,帮助开发者构建高效、可靠的定时任务系统。 ## 传统定时任务方案的痛点分析 在Java发展历程中,定时任务解决方案不断演进,但传统方

gitblog_01000的博客 794

一键生成Microsoft Store应用直链下载:绕过商店故障的终极方案

遇到商店无法加载时,复制链接 → 粘贴到Adguard → 下载主程序包 → 开启开发者模式安装。整个过程耗时不超过2分钟,彻底摆脱商店依赖!

安德洛夫 2183

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

2026年Java面试题

AOF和RDB是两种redis持久化的机制。 重写和重载的区别 ssm原理 servlet生命周期 自定义注解说一说 sleep和wait的区别 map的遍历方式有几种 线程有几种创建方式 说一下图论算法 int有4个字节 mysql的联合索引 linux怎么查看端口号 netstat -tunpl | grep 端口号 fegin怎么暴露出来 fegin有哪些注解 hashMap不是线程安全的,ConcurrentHashMap 是线程安全的 redis和mysql的事物有那么一些不一样 redis幂等

qq_21277357的博客 3355

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Java高并发系统 + 安全监控 完整知识体系

本文系统梳理了Java高并发开发的全方位知识体系,涵盖单机并发基础、分布式架构、系统安全、监控体系和故障治理等核心模块。主要内容包括: 单机并发基础 CPU多级缓存与内存模型 JMM内存模型与happens-before原则 锁机制与CAS原子操作 并发容器与线程池原理 JVM调优与性能优化 分布式高并发架构 分布式锁与一致性算法 缓存体系与典型问题解决方案 消息队列的削峰填谷 负载均衡与分库分表 微服务通信与流量控制 生产级解决方案 高并发业务安全防护 全链路监控体系搭建 典型故障排查与治理 应急预案与性

专注 Java 后端开发,分享基础语法、JVM、并发、Spring 全家桶、微服务、分布式、性能优化等实战干货。坚持输出高质量技术笔记,用简单语言讲清复杂原理,助力每一位 Java 开发者稳步进阶。 574

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【中级Java面试总结】

本文整理了Java开发面试中的常见技术问题,内容涵盖数据库优化、并发控制、设计模式、多线程、Redis、RabbitMQ等多个技术领域。主要包括:数据库查询优化方案、高并发场景下的座位预约设计、防止重复提交的方法、工厂模式解耦原理、线程池配置策略、Redis集群部署方案、消息队列可靠性保证等。同时涉及发散性问题如AI工具应用、系统集成注意事项,以及前端数据传递和性能优化方案。最后分享了针对不同面试官(HR/技术/领导)的自我介绍技巧和群面应对策略,强调项目经验与软实力的差异化展示。全文系统梳理了Java开发

qq_47769481的博客 562

后端常见问题

2.HashMap、 ConcurrentHashMap的底层实现原理3.ArrayList和LinkedList的底层差异及使用场景4.Java异常体系,Checked Exception和Unchecked Exception的区别。1.synchronized和ReentrantLock的实现原理及区别2.volatile关键字的作用和内存语义。3.缓存穿透、缓存击穿、缓存雪崩的解决方案4.Redis内存淘汰策略。1.JVM内存结构:堆、栈、方法区、元空间。1.MySOL索引的数据结构(B+树原理)

sinat_35803474的博客 247

2026 Java后端高频面试宝典

2026 Java后端高频面试宝典(完整版·可直接背诵)风格:通俗理解 + 标准答案 + 场景真题 + 避坑点。适用:校招、实习、1-3年社招、突击面试、日常复盘。五、Spring / SpringBoot 高频。四、MySQL 高频核心(索引+事务+锁)六、Redis 高频面试(必考 100%)一、Java 基础(必问 100%)二、多线程 & 并发(面试重中之重)八、大厂高频场景题(面试加分项)九、面试终极背诵总结(必考短句)七、分布式 & MQ 高频。三、JVM 核心面试题。

PassionAnytime的博客 466

java八股文极速版

时间和空间的权衡 值越高空间开销小但是增加了查找开销服务于从Key映射到index的Hash算法,在性能和内存的使用上取平衡,实现一个尽量均匀分布的Hash函数,选取16,是通过位运算的方法进行求取的。线程安全:当多线程执行同一段程序的时候,如果发生了和预期结果不一致的情况,就是线程不安全的,如果和预期结果一致就是线程安全的,可以加锁解决(把并行运行的线程变成串行化执行)。1.加锁 利用Synchronized或者ReenTrantLock来对不安全对象进行加锁。

PassionAnytime的博客 381

后端大厂面试总结大全

1、首先,通过BeanDefinitionReader 读取指定的配置文件生成bean的定义信息,然后到完整的bean定义信息(BeanDefinition对象),注意这里只是存储bean的定义信息,还没有实例化bean对象;就像工厂里面一样,原材料已经准备好了,但是还没有进行生产,原材料就是beanDefinition,生产就是实例化。2、在 BeanDefinition 和 完整BeanDefinition 中间通过一个后置增强器,可以对bean的定义信息进行统一修改,只需要实现 BeanFactory

zouyang920的博客 426

【Redis】2026 互联网大厂 Redis 面试高频题

**Redis 面试高频题解析: 1. Redis为什么快? 内存操作:数据存储在内存,访问速度比磁盘快千倍。 单线程模型:避免多线程锁竞争和上下文切换,核心命令高效执行。 I/O多路复用:基于epoll实现高并发连接管理,单线程处理万级连接。 高效数据结构:如SDS字符串、跳表等,优化操作复杂度。 2. 单线程如何利用多核CPU? 多线程I/O(Redis 6.0+):网络收发包和协议解析由多线程处理。 多实例部署:绑定不同CPU核心,分散负载。 集群分片:通过Redis Cluster将数据分散到多节点

时光、疏离了记忆づ童话的博客 4024

【RocketMQ】实战使用案例

通过 putUserProperty(String key, String value) 设置,内置系统属性 + 自定义属性:【一】系统内置属性(RocketMQ 识别,不能随意覆盖)(1)MSG_PROP_DELAY 延迟消息等级值:1~18,对应 1s/5s/10s…2h 预设延迟档位作用:定时 / 延迟投递,消息存入延迟队列,到期才分发(2)MSG_PROP_TIMER_TRANS_DELAY 精确定时(5.x+)毫秒时间戳,支持任意精确时间,替代固定等级延迟。

weixin_44823875的博客 118

并行分布式框架:Celery、rq、funboost

Celery是一个异步任务的调度工具,也可以叫做 "分布式任务队列(Distributed Task Queue)"。

freeking101的博客 5万+

面试与压测问题汇总

回答框架(STAR 法则):背景 (S): XX公司业务线众多(金融租赁、保险、营销、物流、发票等),每个迭代需要大量回归测试,手工执行效率低、覆盖不全。任务 (T): 负责设计和开发公司级的 API 自动化测试平台,覆盖多条业务线的接口回归、流程编排和版本对比。基于 Spring Boot + TestNG + llrunner 搭建分层架构设计 Component → Flow → Factory → TestCase 四层架构。

weixin_46921460的博客 554
上一篇: 解决IDEA拉取GitLab项目报错:必须为访问令牌授予作用域[api, read user]
下一篇: 设计模式-适配器模式 Java
刘火锅
博客等级 码龄7年 121粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值