关于Quartz任务不准时执行问题
来源:互联网 发布:苹果电脑图片设计软件 编辑:程序博客网 时间:2024/05/05 10:40
1.前言
也是前段时间工作上遇到这样的问题:quartz定时任务没有在预期的时间执行。后来研究了下quartz的机制,查明了原因,在这做个记录和分享。
2. 原因解释
先看一下spring quartz的大致机制或者说原理。quartz任务由一个主线程和线程池中的多个具体的工作线程构成。
主线程是QuartzSchedulerThread, 主要负责获取具体的定时任务和该任务执行的时间(比如可以通过cron expression 得到时间),并分发任务给线程池。
具体的任务由线程池中的工作线程执行,默认的线程池类是SimpleThreadPool,工作线程是其内部类WorkerThread,默认线程数是10. WorkerThread会领取具体工作任务并执行。
假设10个WorkerThread都在处理任务中(还没处理完各自的任务),假设所有任务都是无状态的(stateless)。而此时第11个任务来到,那么此时就没有空闲的WorkerThread能处理这个任务了。这样造成的现象是:在预期任务执行的时候,任务并没有执行,任务延时了。第11个任务会在某个WorkerThread处理完其任务时,被该WorkerThread领取并处理。
当时工作上遇到的问题即是这样,某些任务花费了很长的时间处理,以至于工作线程全部处在“忙碌”状态,没有空闲线程来及时处理新的任务。
* 默认线程池类,工作线程数都是在quartz jar包中的quartz.properties文件里设置。
3. 代码测试和验证
package test;import org.quartz.CronTrigger;import org.quartz.JobDetail;import org.quartz.Scheduler;import org.quartz.SchedulerFactory;import org.quartz.impl.StdSchedulerFactory; public class TestCronJob { public static void main(String[] args){ SchedulerFactory sf = new StdSchedulerFactory(); try { // below including instantiate QuartzScheduler, // where quartz QuartzSchedulerThread is instantiated. Scheduler sched = sf.getScheduler(); sched.start(); JobDetail jd = new JobDetail("myjob",sched.DEFAULT_GROUP,MyJob.class); System.out.println("stateful:"+jd.isStateful()); CronTrigger ct = new CronTrigger("JobName","DEFAULT","*/10 * * * * ? *"); sched.scheduleJob(jd, ct); }catch(Exception e){ e.printStackTrace(); } }}package test;import java.sql.Timestamp;import java.util.Date;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.quartz.StatefulJob;public class MyJob implements Job{ public void execute(JobExecutionContext arg0) throws JobExecutionException{ System.out.println(new Timestamp(System.currentTimeMillis())+",job executed [" + Thread.currentThread().getName()+"]"); try { Thread.sleep(2*60*1000); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println(new Timestamp(System.currentTimeMillis())+",job executed ["+Thread.currentThread().getName()+"]"); }}
上述代码的效果是:
每10秒执行一下MyJob的任务,MyJob负责打印一些信息。注意执行该任务要花费2分钟(休眠的缘故)。
根据最终输出可以看到,前10个任务准时执行,彼此间隔10s。而第11个任务延时了30s,直到某一个任务执行完之后,第11个任务才被处理。
文章转自:https://my.oschina.net/u/1162561/blog/287588
昨天在工作中突然发现, 如果本地先运行项目,然后修改服务器时间的话,这个作业是不会执行的(即,运行项目时,作业时间必定是晚于当前项目的,), 作业时间是如何获取的可以研究一下。
- 关于Quartz任务不准时执行问题
- Quartz任务不执行问题
- 关于 quartz 1.6.1 的一个死等问题,导致任务不执行
- 关于 quartz 1.6.1 的一个死等问题,导致任务不执行
- 关于 quartz 1.6.1 的一个死等问题,导致任务不执行
- 关于spring的quartz(定时任务执行)问题,
- quartz个别任务不执行处理
- 关于自动执行任务的Quartz框架
- C# Quartz任务执行频率问题
- springmvc + quartz任务调度执行多次问题
- Quartz任务重复执行的问题
- quartz任务执行
- spring quartz 定时任务执行两次的问题
- 解决spring quartz定时任务执行2次的问题
- SSM集成Quartz定时任务 重复执行问题
- SSH:解决Spring整合quartz定时任务执行两次问题
- Spring中quartz任务调度执行两次的问题处理
- crontab linux 定时任务不执行问题
- 关于C# webservice的一些学习记录,供自己学习查阅.
- throw和throws的区别
- python编程练习之三——堆栈和系统管理雏形
- O(∩_∩)O暑假总结
- 请求网络解析json串
- 关于Quartz任务不准时执行问题
- LeetCode-Regular Expression Matching
- 隐私政策
- 数据类型 数据类型转换 运算符
- WOJ1106-String's Puzzle
- BST树转换为有序双向循环链表
- 表达式求值基本构架
- BOM和DOM详解
- 1064: 加密字符