这两个在多数情况下可以替换,所以都不怎么注意两者的区别,前段时间遇到了一个问题,使用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是为了保证数据的即时性的,时间不可以设置太长
所以选用哪种定时任务,还是要看具体的业务场景的,结合业务场景才可以完美解决问题。
附:
http://qinghua.github.io/spring-scheduler/
http://gong1208.iteye.com/blog/1773177
- 每隔指定时间则触发一次,在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean
- 每到指定时间则触发一次,在Quartz中对应的调度器为:org.springframework.scheduling.quartz.CronTriggerBean
CronTriggerBean自带线程