尧图网络 高端网站定制 · 原创设计
免费咨询热线
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/8/22 17:01:10
命令行脚本与浏览器自动化怎么选

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

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

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

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

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

📅 2026/9/10 7:51:40
MORE NEWS

更多资讯

📰

Front-End Checklist 定义列表语义指南:用正确的 dl/dt/dd 结构构建无障碍术语-描述关系

Front-End Checklist 定义列表语义指南:用正确的 dl/dt/dd 结构构建无障碍术语-描述关系 【免费下载链接】Front-End-Checklist 🗂 The essential checklist for modern web development, for humans and AI agents 项目地址: https://gitcode.com/gh_…

📰

Hugo inflect.Singularize 函数详解:模板中英文单词单数化的实现与实战

Hugo inflect.Singularize 函数详解:模板中英文单词单数化的实现与实战 【免费下载链接】hugo The world’s fastest framework for building websites. 项目地址: https://gitcode.com/gh_mirrors/hu/hugo inflect.Singularize 是 Hugo 模板系统中 inflect&…

📰

OpenCode CLI 治理实战:用 agent-governance-opencode 插件守护每一次会话、提示词与工具调用

OpenCode CLI 治理实战:用 agent-governance-opencode 插件守护每一次会话、提示词与工具调用 【免费下载链接】agent-governance-toolkit AI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engine…

📰

PDF转Markdown能不能零配置?双栏论文一次转成可编辑文本

PDF转Markdown能不能零配置?双栏论文一次转成可编辑文本 【免费下载链接】Dolphin The official repo for “Dolphin: Document Image Parsing via Heterogeneous Anchor Prompting”, ACL, 2025. 项目地址: https://gitcode.com/GitHub_Trending/dolphin33/Dolph…

📰

Fantasy Land 实现生态大赏:Sanctuary、Fluture、Folktale 等 20+ 库对比

Fantasy Land 实现生态大赏:Sanctuary、Fluture、Folktale 等 20 库对比 【免费下载链接】fantasy-land Specification for interoperability of common algebraic structures in JavaScript 项目地址: https://gitcode.com/gh_mirrors/fa/fantasy-land Fant…

📰

npm EPERM 报错排查:.npmrc 写入权限问题原理与解决方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

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

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

📞 💬