定时任务Quartz和spring task
这两个在多数情况下可以替换,所以都不怎么注意两者的区别,前段时间遇到了一个问题,使用Spring task,莫名其妙的不执行job了,Log下了日志,看了一下,发现停止在了一个耗时操作上(不会结束,等待响应状态),之前一直没有问题,于是就对比了一下代码的版本,发现了区别:
1、tomcat启动改成了SpringBoot
2、quartz改成了Springtask
第一个是容器的变动,一般不会有问题
第二个值得怀疑,
于是查看了org.springframework.scheduling.quartz.SchedulerFactoryBean这个源码,发现是多线程的,而Springtask默认是单线程
所以在任务没有结束的时候Springtask继续等待,而quartz另起线程执行,
于是解决的办法就出来了:
解决方法1:如下配置pool-size,但这样会导致同一个task前一个还没跑完后面又被触发的问题。
<task:scheduler id="scheduler" pool-size="2" />
解决方法2:让任务分别运行在不同的scheduler里就好了,这样每个job独立运行,不会因为一个job堵塞而停止运行
<task:scheduler id="myScheduler1"/> <task:scheduler id="myScheduler2"/> <task:scheduled-tasks scheduler="myScheduler1"> <task:scheduled ref="doSomethingTask" method="doSomething" cron="${0 * * * * *}"/> </task:scheduled-tasks> <task:scheduled-tasks scheduler="myScheduler2"> <task:scheduled ref="doOtherThingTask" method="doOtherThing" cron="${0 * * * * *}"/> </task:scheduled-tasks>
解决方法3:使用quartz,遇到堵塞,另起线程处理
解决方法4:另添加线程池,然job在线程池中运运行
综合起来无非就是一个:多线程。基本保证了每一个job独立,准时运行。
这里又有几个典型问题
1、为什么不全部默认多线程,Springtask单线程有何意义?
可以保证一段时间内job只执行一次,避免执行冲突与重复操作
2、可以时间设置长一点,就不会有执行冲突与重复操作了?
有的job是为了保证数据的即时性的,时间不可以设置太长
所以选用哪种定时任务,还是要看具体的业务场景的,结合业务场景才可以完美解决问题。
附:
- 每隔指定时间则触发一次,在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean
- 每到指定时间则触发一次,在Quartz中对应的调度器为:org.springframework.scheduling.quartz.CronTriggerBean
CronTriggerBean自带线程
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
前端行业发展和职业规划