首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

quartz 多线程如何规避同一时刻执行同一JOB两个或两个以上

quartz 多线程如何规避同一时刻执行同一JOB两个或两个以上

java自动运行任务job---quartz的运用


但是我们发现如果同一个job同一时刻运行,可能造成重复入库的情况。


所以我们会有这样的需求 :


希望多线程时,能够控制同一时刻相同JOB只能有一个在执行。
原因是由于我的执行频率是每30秒,然而有可能30后该JOB还没结素,结果另一线程再次启用同一JOB下的方法,我希望在前一个此JOB结束后再进行下一次调用


其实很简单,我们只要在detail的参数里加上一句话就行了,把这个job设置成有状态的job

<property name="concurrent" value="false" /> ③ 指定最终封装出的任务是否有状态

如下:


    <bean id="jobDetail_1"
    class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject" ref="myService" /> ① 引用一个Bean
    <property name="targetMethod" value="doJob" /> ② 指定目标Bean的方法
    <property name="concurrent" value="false" /> ③ 指定最终封装出的任务是否有状态
    <bean id="myService" class="com.baobaotao.service.MyService"/>


obDetail_1将MyService#doJob()封装成一个任务,同时通过concurrent属性指定任务的类型,默认情况下封装为无状态的任务,如果希望目标封装为有状态的任务,仅需要将concurrent设置为false就可以了。Spring通过名为concurrent的属性指定任务的类型,能够更直接地描述到任务执行的方式(有状态的任务不能并发执行,无状态的任务可并发执行),对于不熟悉Quartz内部机制的用户来说,比起statefule,concurrent显然更简明达意些。



1.关于有状态JOB(StatefulJob)



网上有很多关于有状态JOB的作用与使用的文章,我借鉴下,做下简单的说明:

a). 实现有状态JOB只需要实现org.quartz.StatefulJob 接口即可,StatefulJob 接口仅仅是扩展了 Job 接口,未加入新的方法.



b). Job(无状态)和 StatefulJob 在框架中使用中存在两个关键差异。首先,JobDataMap 在每次执行之后重新持久化到JobStore 中。这样就确保你对 Job 数据的改变直到下次执行仍然保持着。你可以在有状态 Job 中简单的通过 map 的 put() 方法来修改 JobDataMap.已存在的任何数据会被新的数据覆盖掉。你也能对无状态的 Job 这么做,但是因为对于无状态 Job 来说,JobDataMap 不会持久化,所以数据不会保存下来。  

     

c).  两个或多个有状态的 JobDetail 实例不能并发执行。说的是你创建并注册了一个有状态 JobDetail 到 Scheduler 上。你还建立了两个 Trigger 来触发这个 Job:一个每五分钟触发,另一个也是每五分钏触发。假如这两个 Trigger 试图在同一时刻触发 Job,框架是不允许这种事情发生的。第二个 Trigger 一直会被阻塞直到第一个结束。


注意:

在使用quartz1.6版本的时候,我碰到过比较麻烦的问题,后来在iteye和csdn求助都没有解决.还是从国外的文章上找到了一些眉目解决了.

    在实现SteafulJob接口后,该JOB怎么搞都只执行一次.


解决方案:

把1.6版本替换成Quartz2.0版本
返回列表