尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
深入理解 @DisallowConcurrentExecution:防止并发执行的利器
1. 引言在分布式系统、定时任务调度或高并发场景下我们常常需要确保某个任务在同一时刻只能有一个实例在执行。例如一个处理关键数据的定时任务如果被并发执行可能会导致数据不一致、重复处理等严重问题。为了解决这类问题Quartz 等任务调度框架提供了DisallowConcurrentExecution注解。本文将深入探讨DisallowConcurrentExecution注解的原理、使用场景、配置方法以及注意事项帮助你更好地在项目中应用它来保证任务的串行执行。2. DisallowConcurrentExecution 是什么DisallowConcurrentExecution是 Quartz 作业调度框架中的一个注解用于标记一个 Job 类。当一个 Job 类被此注解修饰时Quartz 调度器会确保同一时刻同一个 JobDetail由 JobKey 标识最多只有一个实例在执行。这意味着即使该 Job 的触发时间到了如果上一个实例尚未执行完毕新的触发将会被阻塞直到前一个实例完成。这有效避免了任务的并发执行。核心特性作用对象Job 类org.quartz.Job的实现类。并发控制粒度基于JobKey。相同JobKey的 Job 实例会被串行化。框架依赖主要用于 Quartz 框架。3. 如何使用 DisallowConcurrentExecution使用非常简单只需在实现Job接口的类上添加该注解即可。3.1 基本用法示例importorg.quartz.Job;importorg.quartz.JobExecutionContext;importorg.quartz.JobExecutionException;importorg.quartz.DisallowConcurrentExecution;// 关键在类级别添加注解DisallowConcurrentExecutionpublicclassMySensitiveDataProcessJobimplementsJob{Overridepublicvoidexecute(JobExecutionContextcontext)throwsJobExecutionException{// 模拟一个耗时操作try{System.out.println(开始执行关键数据处理任务时间: newDate());Thread.sleep(5000);// 睡眠5秒模拟任务执行时间System.out.println(关键数据处理任务执行完毕时间: newDate());}catch(InterruptedExceptione){Thread.currentThread().interrupt();thrownewJobExecutionException(e);}}}3.2 配置与调度接下来你需要通过Scheduler来调度这个 Job。这里展示一个简单的调度示例importorg.quartz.*;importorg.quartz.impl.StdSchedulerFactory;importstaticorg.quartz.JobBuilder.newJob;importstaticorg.quartz.TriggerBuilder.newTrigger;importstaticorg.quartz.SimpleScheduleBuilder.simpleSchedule;publicclassQuartzSchedulerExample{publicstaticvoidmain(String[]args)throwsSchedulerException{// 1. 获取调度器实例SchedulerschedulerStdSchedulerFactory.getDefaultScheduler();scheduler.start();// 2. 定义JobDetail指定唯一的JobKeyJobDetailjobnewJob(MySensitiveDataProcessJob.class).withIdentity(dataProcessJob,group1)// JobKey: namedataProcessJob, groupgroup1.build();// 3. 定义Trigger每3秒触发一次触发间隔小于Job执行时间5秒TriggertriggernewTrigger().withIdentity(trigger1,group1).startNow().withSchedule(simpleSchedule().withIntervalInSeconds(3)// 每3秒触发一次.repeatForever()).build();// 4. 将Job和Trigger注册到调度器scheduler.scheduleJob(job,trigger);}}运行上述代码观察输出由于 Job 执行需要 5 秒而 Trigger 每 3 秒就会触发一次。如果没有DisallowConcurrentExecution日志会显示任务重叠执行。添加了该注解后你会发现输出类似于开始执行关键数据处理任务时间: Wed Jul 23 09:19:40 CST 2026 关键数据处理任务执行完毕时间: Wed Jul 23 09:19:45 CST 2026 开始执行关键数据处理任务时间: Wed Jul 23 09:19:45 CST 2026 // 注意上一次执行完毕后下一次才立即开始 关键数据处理任务执行完毕时间: Wed Jul 23 09:19:50 CST 2026这表明即使触发周期3秒小于任务执行时间5秒同一JobKey的任务也被强制串行执行了。4. 工作原理与注意事项4.1 工作原理Quartz 调度器在触发一个 Job 前会检查该 Job 类是否带有DisallowConcurrentExecution注解。如果有调度器会检查当前是否有相同 JobKey的实例正在执行。如果存在本次触发将会被跳过根据 misfire 策略处理直到正在执行的实例完成。4.2 重要注意事项粒度是 JobKey不是 Job 类DisallowConcurrentExecution控制的是相同JobKey的并发。如果你为同一个 Job 类创建了多个不同JobKey的JobDetail它们之间仍然可以并发执行。// JobDetail AJobDetailjobAnewJob(MyJob.class).withIdentity(jobA,group1).build();// JobDetail BJobDetailjobBnewJob(MyJob.class).withIdentity(jobB,group1).build();// jobA 和 jobB 即使属于同一个MyJob类也可以并发执行因为它们的JobKey不同。与PersistJobDataAfterExecution结合使用如果 Job 需要持久化JobDataMap中的数据即在多次执行间保持状态通常需要同时使用PersistJobDataAfterExecution注解。而且官方建议这两个注解一起使用以避免数据更新时出现竞态条件。DisallowConcurrentExecutionPersistJobDataAfterExecutionpublicclassMyStatefulJobimplementsJob{// ...}对性能的影响该注解通过串行化执行来保证数据安全这可能会影响系统的吞吐量。如果任务本身是幂等的且允许并发或者执行频率很低则不一定需要此注解。不是分布式锁DisallowConcurrentExecution是 Quartz 在单个调度器实例JVM 进程内提供的并发控制。在集群部署的 Quartz 环境中需要通过配置数据库持久化org.quartz.jobStore.isClustered true并结合数据库行锁来实现跨节点的并发控制。5. 总结DisallowConcurrentExecution是一个简单而强大的工具用于解决任务调度中的并发安全问题。它通过确保同一任务JobKey的串行执行防止了因并发导致的数据混乱。在以下场景中尤其有用处理非幂等性操作如文件写入、数据库状态更新。执行资源敏感型任务如占用大量内存或 CPU。需要严格顺序执行的业务流程。在使用时务必理解其控制粒度JobKey以及与集群环境的配合方式从而做出最合适的设计决策。
RELATED

相关推荐

无头浏览器能做什么,又不能做什么

无头浏览器能做什么,又不能做什么

一、先把问题边界说清楚 无头模式适合可重复页面交互与回归验证,但不能绕过权限、验证码或站点规则。很多失败并不是工具本身失效,而是输入、状态、依赖和成功条件没有定义清楚。开始动手前,先写下触发条件、期望结果、允许的副作用和停止条件…

📅 2026/9/19 3:47:46
命令行脚本与浏览器自动化怎么选

命令行脚本与浏览器自动化怎么选

一、先把问题边界说清楚 有稳定接口或文件输入时优先命令行;只有页面交互入口时再使用浏览器驱动。很多失败并不是工具本身失效,而是输入、状态、依赖和成功条件没有定义清楚。开始动手前,先写下触发条件、期望结果、允许的副作用和停止条件&…

📅 2026/9/19 3:50:55
训练-推理-反馈闭环缺失=伪AI!普通软件开发者的3个致命认知盲区,现在纠正还来得及

训练-推理-反馈闭环缺失=伪AI!普通软件开发者的3个致命认知盲区,现在纠正还来得及

更多请点击: https://kaifayun.com 第一章:训练-推理-反馈闭环缺失伪AI!普通软件开发者的3个致命认知盲区,现在纠正还来得及 很多开发者把调用一次 OpenAI API 或加载一个 Hugging Face 模型就当作“做了 AI”,却从未…

📅 2026/10/7 8:59:50
MORE NEWS

更多资讯

📰

AMD MI250部署DeepSeek-V4-Flash:先修正确性再谈性能

前阵子帮朋友在实验室的 AMD MI250(CDNA2)机器上部署 DeepSeek-V4-Flash,模型倒是跑起来了,GPU 利用率也看着正常,可生成出来的内容总透着一股“不对劲”——有些句子读不通,有些甚至出现重复 token 的死循…

📰

会用AI工具不等于具备AI实力:完整项目才是能力证明

"熟练使用AI工具"这句话,最近越来越多地出现在简历、作品集和项目介绍里,人人都想用它证明自己的真实能力,但真正能做到的人少之又少。前阵子我帮朋友做了一轮AI方向的实战评估,候选人里十个有八个说自己日常用Kimi、De…

📰

CUDA手写SGEMM优化实战:从0.4到10.23 TFLOPS的完整优化链路

先说结论:我没用 Tensor Core,没上 cuBLAS,就是老老实实用 CUDA C 手写 SGEMM(单精度矩阵乘法),在 RTX 3090 上把性能从最初的 0.4 TFLOPS 一路提到 10.23 TFLOPS,也就是跨过了 10000 GFLOPS 这…

📰

WordPress博客贡献热力图开发指南

1. 项目背景与核心价值 作为一名长期运营技术博客的创作者,我一直在寻找能够直观展示写作活跃度的解决方案。GitHub的贡献热力图给了我灵感——那种通过颜色梯度清晰呈现每日活跃度的设计,既美观又实用。但在WordPress生态中,并没有现成的插件…

📰

拆解 Agent Harness:大模型智能体的七个核心模块与最小实现

做 agent 相关项目的人这两年大概都有同一个体感:模型能力每隔几个月就往上跳一档,但真正卡住产品落地的,往往不是模型,而是模型外面那一圈东西。这一圈东西,业内现在有个比较统一的叫法——Agent Harness,…

📰

ArcGIS外业质检插件开发:提升农田调查效率的解决方案

1. 项目背景与痛点分析 在外业调查项目中,质检环节一直是让从业人员头疼的"老大难"问题。以高标准农田外调项目为例,一个完整的质检流程通常涉及以下数据源: 空间数据 :存储在ArcMap中的点、线、面要素 属性数据 &…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬