﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-少年阿宾-随笔分类-quartz</title><link>http://www.blogjava.net/stevenjohn/category/52416.html</link><description>那些青春的岁月</description><language>zh-cn</language><lastBuildDate>Sun, 26 Jul 2015 19:18:47 GMT</lastBuildDate><pubDate>Sun, 26 Jul 2015 19:18:47 GMT</pubDate><ttl>60</ttl><item><title>Quartz 并发</title><link>http://www.blogjava.net/stevenjohn/archive/2015/07/26/426425.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sat, 25 Jul 2015 17:39:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/07/26/426425.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/426425.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/07/26/426425.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/426425.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/426425.html</trackback:ping><description><![CDATA[<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.2000007629395px; background-color: #ffffff;">1、</span><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.2000007629395px; background-color: #ffffff;">StatefulJob</span><br /><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.2000007629395px; background-color: #ffffff;">implements StatefulJob使Job成为有状态的，顺序执行&nbsp;</span><br /><div><span style="line-height: 25.2000007629395px;">同一个有状态的job实例不存在并发，无状态的job的并发数由上面配置的线程数决定。不想并发的话，设置成1，第二个线程在前一个执行完以后触发执行。</span></div><div><span style="line-height: 25.2000007629395px;">线程数大于1时，如果存在空闲线程，则到执行时间点即触发执行。</span></div><span style="background-color: #ffffff;"><br />2、</span>MethodInvokingJobDetailFactoryBean<br /><div>MethodInvokingJobDetailFactoryBean的并发问题</div><div>大家在使用quartz的时候，一般只设置了&#8220;targetObject&#8221;和&#8220;targetMethod&#8221;，MethodInvokingJobDetailFactoryBean类默认是并发执行的，这时候如果不设置&#8220;concurrent&#8221;为false，很可能带来并发或者死锁的问题，而且几率较小，不容易复现，请大家使用的时候注意设置&#8220;concurrent&#8221;。</div><div>&nbsp;</div><div>&nbsp; &nbsp; &lt;bean id="cpm.MessageJobFactoryBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;property name="targetObject" ref="cpm.MessageJob"/&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;property name="targetMethod" value="execute"/&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;property name="concurrent" value="false"/&gt;</div><div>&nbsp; &nbsp; &lt;/bean&gt;</div><div>concurrent &nbsp; 同时发生</div><div>&nbsp;concurrent：对于相同的JobDetail，当指定多个Trigger时, 很可能第一个job完成之前，第二个job就开始了。</div><div>&nbsp;定concurrent设为false，多个job不会并发运行，第二个job将不会在第一个job完成之前开始</div><span style="background-color: #ffffff;"><br /><br /><br /><br /></span><div>防止job并行运行的几种解决方案&nbsp;</div><div>一、JOB State&nbsp;</div><div>在通过MethodInvokingJobDetailFactoryBean在运行中动态生成的Job，配置的xml文件有个concurrent属性，表示job是否可以并行运行：如果一个job的业务处理发费的时间超过了job的启动的间隔时间（repeatInterval)，这个属性非常有用。如果为false，那么，在这种情况下，当前job还在运行，那么下一个job只能延时运行。如果为true，那么job就会并行运行。在实际的应用中应该配置为true/false，要根据需要了（废话）。&nbsp;</div><div></div><div></div><div></div><div>二、如果通过继承QuartzJobBean实现job的话，默认情况下QuartzJobBean是implements org.quartz.Job接口的，也就是说job示例是stateless的，会出现前面所述的并行情况。而代码中却要求job任务必需串行，解决办法：在job子类中继续implements org.quartz.StatefulJob。那么这个job实例变成了Stateful，job任务也就是串行的了。</div><div></div><div>注：&nbsp;</div><div></div><div>在Quartz中，如果实现org.quartz.Job接口，那么这个job是stateless的，job实例的参数不能在多个任务之间共享，如果实现org.quartz.StatefulJob，这个job是个单例的，job实例的属性可以从当前任务传递到下一个任务。&nbsp;</div><div></div><span style="background-color: #ffffff;"><br /><br /></span><div>spring和quartz的整合对版本是有要求的。</div><div></div><div>spring3.1以下的版本必须使用quartz1.x系列，3.1以上的版本才支持quartz 2.x，不然会出错。</div><span style="background-color: #ffffff;"><br /></span><div>至于原因，则是spring对于quartz的支持实现，org.springframework.scheduling.quartz.CronTriggerBean继承了org.quartz.CronTrigger，在quartz1.x系列中org.quartz.CronTrigger是个类，而在quartz2.x系列中org.quartz.CronTrigger变成了接口，从而造成无法用spring的方式配置quartz的触发器（trigger）。<br /><br /><div>在Spring中使用Quartz有两种方式实现：第一种是任务类继承QuartzJobBean，第二种则是在配置文件里定义任务类和要执行的方法，类和方法可以是普通类。很显然，第二种方式远比第一种方式来的灵活。</div><br /><br /><br />MethodInvokingJobDetailFactoryBean中concurrent和shouldRecover属性的作用  <br /><strong>解释</strong> concurrent为true，则允许一个QuartzJob并发执行，否则就是顺序执行。例如QuartzJob  A执行时间为15秒，配置为每10秒执行一次；如果concurrent为true，则0秒的时候启动一次A，10秒的时候再启动一次A，20秒的时候再启动一次A，不管前面启动的A有没有执行完；如果concurrent为false，则0秒的时候启动一次A，15秒的时候A执行完毕，再第二次启动A。  <br />shouldRecover属性为true，则当Quartz服务被中止后，再次启动或集群中其他机器接手任务时会尝试恢复执行之前未完成的所有任务。例如QuartzJob  B，在每次00秒的时候启动，假如在03:00的任务执行完之后服务器1被中止，服务器2在05:15的时候才接手；如果shouldRecover属性为true，则服务器2会尝试着补回原来在04:00和05:00的时候应该做的任务，如果shouldRecover属性为false，则服务器2只会从06:00的时候再执行B。<br /><br /><br /><pre>Quartz集群只支持JDBCJobStore存储方式，而MethodInvokingJobDetailF<wbr>actoryBean不能序列化存储job数据到数据库，</pre><div>重写 quartz 的 QuartzJobBean 类&nbsp;</div><div>原因是在使用 quartz+spring 把 quartz 的 task 实例化进入数据库时，会产生： serializable 的错误，原因在于：</div><div>这个 MethodInvokingJobDetailFactoryBean 类中的 methodInvoking 方法，是不支持序列化的，因此在把 QUARTZ 的 TASK 序列化进入数据库时就会抛错。网上有说把 SPRING 源码拿来，修改一下这个方案，然后再打包成 SPRING.jar 发布，这些都是不好的方法，是不安全的。</div><div>必须根据 QuartzJobBean 来重写一个自己的类 。</div><div></div><br /><br /></div><img src ="http://www.blogjava.net/stevenjohn/aggbug/426425.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-07-26 01:39 <a href="http://www.blogjava.net/stevenjohn/archive/2015/07/26/426425.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>quartz 数据表</title><link>http://www.blogjava.net/stevenjohn/archive/2015/07/23/426393.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Thu, 23 Jul 2015 07:31:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/07/23/426393.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/426393.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/07/23/426393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/426393.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/426393.html</trackback:ping><description><![CDATA[<span style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_CALENDARS 以 Blob 类型存储 Quartz 的 Calendar 信</span><span style="color: #464646; font-family: simsun; background-color: #dcdcdc;">息&nbsp;</span><wbr style="color: #464646; font-family: simsun; background-color: #dcdcdc;"><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_CRON_TRIGGERS 存储 Cron Trigger，包括 Cron表达式和时区信息&nbsp;<wbr></div><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_FIRED_TRIGGERS 存储与已触发的 Trigger 相关的状态信息，以及相联 Job的执行信息QRTZ_PAUSED_TRIGGER_GRPS 存储已暂停的 Trigger 组的信息&nbsp;<wbr></div><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_SCHEDULER_STATE 存储少量的有关 Scheduler 的状态信息，和别的 Scheduler实例(假如是用于一个集群中)&nbsp;<wbr></div><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_LOCKS 存储程序的<span style="word-wrap: normal; word-break: normal;">悲</span>观锁的信息(假如使用了悲观锁)&nbsp;<wbr></div><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_JOB_DETAILS 存储每一个已配置的 Job 的详细信息&nbsp;<wbr></div><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_JOB_LISTENERS 存储有关已配置的 JobListener 的信息&nbsp;<wbr></div><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_SIMPLE_TRIGGERS 存储简单的Trigger，包括重复次数，间隔，以及已触的次数&nbsp;<wbr></div><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_BLOG_TRIGGERS Trigger 作为 Blob 类型存储(用于 Quartz 用户用 JDBC创建他们自己定制的 Trigger 类型，JobStore 并不知道如何存储实例的时候)&nbsp;<wbr></div><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_TRIGGER_LISTENERS 存储已配置的 TriggerListener 的信息&nbsp;<wbr></div><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">QRTZ_TRIGGERS 存储已配置的 Trigger 的信息&nbsp;<wbr></div><div style="color: #464646; font-family: simsun; background-color: #dcdcdc;">--------------------------------------------------------------------------------------------------<div></div><div><span style="word-wrap: normal; word-break: normal; line-height: 26px; color: #555b6e; font-family: Arial; font-weight: bold; text-indent: 8px; background-color: #ffffff;">quartz 持久化数据库表格字段解释</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">建表,SQL语句在quartz-1.6.6\docs\dbTables文件夹中可以找到,介绍下主要的几张表：&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;表qrtz_job_details: 保存job详细信息,该表需要用户根据实际情况初始化&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;job_name:集群中job的名字,该名字用户自己可以随意定制,无强行要求&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;job_group:集群中job的所属组的名字,该名字用户自己随意定制,无强行要求&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;job_class_name:集群中个note job实现类的完全包名,quartz就是根据这个路径到classpath找到该job类&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;is_durable:是否持久化,把该属性设置为1，quartz会把job持久化到数据库中&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;job_data:一个blob字段，存放持久化job对象&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;表qrtz_triggers: 保存trigger信息&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;trigger_name: trigger的名字,该名字用户自己可以随意定制,无强行要求&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;trigger_group:trigger所属组的名字,该名字用户自己随意定制,无强行要求&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;job_name: qrtz_job_details表job_name的外键&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;job_group: qrtz_job_details表job_group的外键&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;trigger_state:当前trigger状态，设置为ACQUIRED,如果设置为WAITING,则job不会触发&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;trigger_cron:触发器类型,使用cron表达式&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;表qrtz_cron_triggers:存储cron表达式表&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;trigger_name: qrtz_triggers表trigger_name的外键&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;trigger_group: qrtz_triggers表trigger_group的外键&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;cron_expression:cron表达式&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;表qrtz_scheduler_state:存储集群中note实例信息，quartz会定时读取该表的信息判断集群中每个实例的当前状态&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;instance_name:之前配置文件中org.quartz.scheduler.instanceId配置的名字，就会写入该字段，如果设置为AUTO,quartz会根据物理机名和当前时间产生一个名字&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;last_checkin_time:上次检查时间&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;checkin_interval:检查间隔时间&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><strong style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">步骤4</strong><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">:&nbsp;<wbr></span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">&nbsp;<wbr>配置quartz.properties文件：</span><br style="line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;" /><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#调度标识名 集群中每一个实例都必须使用相同的名称&nbsp;org.quartz.scheduler.instanceName = scheduler</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#ID设置为自动获取 每一个必须不同&nbsp;org.quartz.scheduler.instanceId = AUTO</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#数据保存方式为持久化 org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#数据库平台 org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate #数据库别名 随便取org.quartz.jobStore.dataSource = myXADS</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#表的前缀 org.quartz.jobStore.tablePrefix = QRTZ_</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#设置为TRUE不会出现序列化非字符串类到 BLOB 时产生的类版本问题 org.quartz.jobStore.useProperties = true</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#加入集群 org.quartz.jobStore.isClustered = true</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#调度实例失效的检查时间间隔&nbsp;org.quartz.jobStore.clusterCheckinInterval = 20000&nbsp;<wbr></span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#容许的最大作业延长时间&nbsp;org.quartz.jobStore.misfireThreshold = 60000</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#ThreadPool 实现的类名 org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#线程数量 org.quartz.threadPool.threadCount = 10</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#线程优先级 org.quartz.threadPool.threadPriority = 5</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#自创建父线程 org.quartz.threadPool.threadsInheritContextCla<wbr>ssLoaderOfInitializingTh<wbr>read = true&nbsp;<wbr></span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#设置数据源org.quartz.dataSource.myXADS.jndiURL = CT</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">#jbdi类名 org.quartz.dataSource.myXADS.java.naming.factory.initial = weblogic.jndi.WLInitialContextFactory #URLorg.quartz.dataSource.myXADS.java.naming.provider.url = t3://localhost:7001</span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;"><br /></span></div><div><span style="word-wrap: normal; word-break: normal; line-height: normal; color: #2a2929; font-family: Arial; font-size: 12px; background-color: #ffffff;">【注】：在J2EE工程中如果想用数据库管理Quartz的相关信息，就一定要配置数据源，这是Quartz的要求。</span></div></div><img src ="http://www.blogjava.net/stevenjohn/aggbug/426393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-07-23 15:31 <a href="http://www.blogjava.net/stevenjohn/archive/2015/07/23/426393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>纯代码实现Quartz定时器(二)</title><link>http://www.blogjava.net/stevenjohn/archive/2012/08/25/386255.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sat, 25 Aug 2012 04:43:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/08/25/386255.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/386255.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/08/25/386255.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/386255.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/386255.html</trackback:ping><description><![CDATA[<p>package com.abin.lee.quartz.all;</p>
<p>import org.quartz.Job;<br />import org.quartz.JobExecutionContext;<br />import org.quartz.JobExecutionException;</p>
<p>public class UniversalQuartz implements Job{</p>
<p>&nbsp;public void execute(JobExecutionContext arg0) throws JobExecutionException {<br />&nbsp;&nbsp;System.out.println("执行定时任务: "+System.currentTimeMillis());<br />&nbsp;&nbsp;<br />&nbsp;}<br />&nbsp;<br />}<br /><br /><br /><br /><br /></p>
<p>package com.abin.lee.quartz.all;</p>
<p>import java.text.ParseException;<br />import java.util.Date;</p>
<p>import org.quartz.CronTrigger;<br />import org.quartz.JobDetail;<br />import org.quartz.Scheduler;<br />import org.quartz.SchedulerException;<br />import org.quartz.SchedulerFactory;</p>
<p>public class UniversalQuartzManager {<br />&nbsp;private static UniversalQuartzManager instance = null;<br />&nbsp;private Scheduler sched = null;<br />&nbsp;private SchedulerFactory factory = null;</p>
<p>&nbsp;private UniversalQuartzManager() {<br />&nbsp;&nbsp;_init();<br />&nbsp;}</p>
<p>&nbsp;private void _init() {<br />&nbsp;&nbsp;factory = new org.quartz.impl.StdSchedulerFactory();<br />&nbsp;&nbsp;try {<br />&nbsp;&nbsp;&nbsp;sched = factory.getScheduler();<br />&nbsp;&nbsp;} catch (SchedulerException e) {<br />&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />&nbsp;&nbsp;}<br />&nbsp;}</p>
<p>&nbsp;public synchronized static UniversalQuartzManager getInstance() {<br />&nbsp;&nbsp;if (instance == null) {<br />&nbsp;&nbsp;&nbsp;instance = new UniversalQuartzManager();<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;return instance;<br />&nbsp;}</p>
<p>&nbsp;public void start() {<br />&nbsp;&nbsp;try {<br />&nbsp;&nbsp;&nbsp;sched.start();<br />&nbsp;&nbsp;&nbsp;// 在这里加载需要执行的业务逻辑类UniversalQuartz.class<br />&nbsp;&nbsp;&nbsp;JobDetail detail = new JobDetail("cmhksynchron", "cmhkSynch",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UniversalQuartz.class);<br />&nbsp;&nbsp;&nbsp;CronTrigger trigger = new CronTrigger();<br />&nbsp;&nbsp;&nbsp;// 手动添加了时间<br />&nbsp;&nbsp;&nbsp;trigger.setCronExpression("0/10 * * * * ? *");<br />//&nbsp;&nbsp;&nbsp;trigger.setCronExpression("0 0-59 16 * * ?");<br />&nbsp;&nbsp;&nbsp;trigger.setName("abintrigger");<br />&nbsp;&nbsp;&nbsp;trigger.setStartTime(new Date());<br />&nbsp;&nbsp;&nbsp;sched.scheduleJob(detail, trigger);<br />&nbsp;&nbsp;} catch (SchedulerException e) {<br />&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />&nbsp;&nbsp;} catch (ParseException e2) {<br />&nbsp;&nbsp;&nbsp;e2.printStackTrace();<br />&nbsp;&nbsp;}<br />&nbsp;}</p>
<p>&nbsp;public void stop() {<br />&nbsp;&nbsp;try {<br />&nbsp;&nbsp;&nbsp;sched.shutdown();<br />&nbsp;&nbsp;&nbsp;sched = factory.getScheduler();<br />&nbsp;&nbsp;} catch (SchedulerException e) {<br />&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />&nbsp;&nbsp;}<br />&nbsp;}</p>
<p>&nbsp;public void refresh() {<br />&nbsp;&nbsp;// 未知的原因，程序执行这段判断进入stop（），在sched.shutdown();这一句报错，//所以暂时将其屏蔽，以待后来解决<br />&nbsp;&nbsp;// try {<br />&nbsp;&nbsp;// if(sched != null &amp;&amp; sched.isStarted()) {<br />&nbsp;&nbsp;// this.stop();<br />&nbsp;&nbsp;// }<br />&nbsp;&nbsp;this.start();<br />&nbsp;&nbsp;// } catch (SchedulerException e) {<br />&nbsp;&nbsp;// e.printStackTrace();<br />&nbsp;&nbsp;// }<br />&nbsp;}</p>
<p>}<br /></p>
<p>&nbsp;</p><br /><br /><br />
<p>package com.abinl.lee.quartz.all.test;</p>
<p>import com.abin.lee.quartz.all.UniversalQuartzManager;</p>
<p>public class TestQuartz {<br />&nbsp;public static void main(String[] args) {<br />&nbsp;&nbsp;UniversalQuartzManager.getInstance().refresh();&nbsp;<br />&nbsp;}</p>
<p>}<br /></p><br /><br /> <img src ="http://www.blogjava.net/stevenjohn/aggbug/386255.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-08-25 12:43 <a href="http://www.blogjava.net/stevenjohn/archive/2012/08/25/386255.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>纯代码实现Quartz定时器(一)</title><link>http://www.blogjava.net/stevenjohn/archive/2012/08/25/386253.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sat, 25 Aug 2012 03:48:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/08/25/386253.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/386253.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/08/25/386253.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/386253.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/386253.html</trackback:ping><description><![CDATA[<div id="article_content" class="article_content">
<p>深入解读Quartz的原理<br />&nbsp;<br />Quartz是一个大名鼎鼎的Java版开源定时调度器，功能强悍，使用方便。<br />&nbsp;<br />一、核心概念<br />&nbsp;<br />Quartz的原理不是很复杂，只要搞明白几个概念，然后知道如何去启动和关闭一个调度程序即可。<br />&nbsp;<br />1、Job<br />表示一个工作，要执行的具体内容。此接口中只有一个方法<br />void execute(JobExecutionContext context)<br />&nbsp;<br />2、JobDetail<br />JobDetail表示一个具体的可执行的调度程序，Job是这个可执行程调度程序所要执行的内容，另外JobDetail还包含了这个任务调度的方案和策略。</p>
<p>&nbsp;<br />3、Trigger代表一个调度参数的配置，什么时候去调。<br />&nbsp;<br />4、Scheduler代表一个调度容器，一个调度容器中可以注册多个JobDetail和Trigger。当Trigger与JobDetail组合，就可以被Scheduler容器调度了。<br />&nbsp;<br />&nbsp;<br />二、一个最简单入门实例<br />&nbsp;<br />import org.quartz.*; <br />import org.quartz.impl.StdSchedulerFactory; </p>
<p>import java.util.Date; </p>
<p>/** <br />* quartz定时器测试 <br />* <br />* @author leizhimin 2009-7-23 8:49:01 <br />*/ <br />public class MyJob implements Job { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(new Date() + ": doing something..."); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />} </p>
<p>class Test { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //1、创建JobDetial对象 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JobDetail jobDetail = new JobDetail(); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置工作项 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jobDetail.setJobClass(MyJob.class); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jobDetail.setName("MyJob_1"); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jobDetail.setGroup("JobGroup_1"); </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //2、创建Trigger对象 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SimpleTrigger strigger = new SimpleTrigger(); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strigger.setName("Trigger_1"); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strigger.setGroup("Trigger_Group_1"); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strigger.setStartTime(new Date()); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置重复停止时间，并销毁该Trigger对象 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.util.Calendar c = java.util.Calendar.getInstance(); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c.setTimeInMillis(System.currentTimeMillis() + 1000 * 1L); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strigger.setEndTime(c.getTime()); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strigger.setFireInstanceId("Trigger_1_id_001"); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置重复间隔时间 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strigger.setRepeatInterval(1000 * 1L); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置重复执行次数 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strigger.setRepeatCount(3); </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //3、创建Scheduler对象，并配置JobDetail和Trigger对象 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SchedulerFactory sf = new StdSchedulerFactory(); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Scheduler scheduler = null; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scheduler = sf.getScheduler(); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scheduler.scheduleJob(jobDetail, strigger); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //4、并执行启动、关闭等操作 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scheduler.start(); </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (SchedulerException e) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace(); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try { <br />//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //关闭调度器 <br />//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scheduler.shutdown(true); <br />//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (SchedulerException e) { <br />//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace(); <br />//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />}<br />&nbsp;<br />执行结果：</p>
<p>&nbsp;<br />当把结束时间改为：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置重复停止时间，并销毁该Trigger对象 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java.util.Calendar c = java.util.Calendar.getInstance(); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c.setTimeInMillis(System.currentTimeMillis() + 1000 * 1L); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strigger.setEndTime(c.getTime());<br />&nbsp;<br />执行结果：<br />&nbsp;<br />当添加一条关闭调度器的语句：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //4、并执行启动、关闭等操作 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scheduler.start(); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scheduler.shutdown(true); </p>
<p>&nbsp;<br />程序执行结果：<br />Thu Jul 23 10:11:50 CST 2009: doing something... </p>
<p>Process finished with exit code 0<br />仅仅执行了一次，这一次能执行完，原因是设定了scheduler.shutdown(true);true表示等待本次任务执行完成后停止。<br />&nbsp;<br />从这里也可以看出，scheduler是个容器，scheduler控制jobDetail的执行，控制的策略是通过trigger。<br />&nbsp;<br />当scheduler容器启动后，jobDetail才能根据关联的trigger策略去执行。当scheduler容器关闭后，所有的jobDetail都停止执行。<br />&nbsp;<br />三、透过实例看原理<br />&nbsp;<br />通过研读Quartz的源代码，和本实例，终于悟出了Quartz的工作原理。<br />&nbsp;<br />1、scheduler是一个计划调度器容器（总部），容器里面可以盛放众多的JobDetail和trigger，当容器启动后，里面的每个JobDetail都会根据trigger按部就班自动去执行。<br />&nbsp;<br />2、JobDetail是一个可执行的工作，它本身可能是有状态的。<br />&nbsp;<br />3、Trigger代表一个调度参数的配置，什么时候去调。<br />&nbsp;<br />4、当JobDetail和Trigger在scheduler容器上注册后，形成了装配好的作业（JobDetail和Trigger所组成的一对儿），就可以伴随容器启动而调度执行了。<br />&nbsp;<br />5、scheduler是个容器，容器中有一个线程池，用来并行调度执行每个作业，这样可以提高容器效率。<br />&nbsp;<br />6、将上述的结构用一个图来表示，如下：<br />&nbsp;</p>
<p>&nbsp;<br />四、总结<br />&nbsp;<br />1、搞清楚了上Quartz容器执行作业的的原理和过程，以及作业形成的方式，作业注册到容器的方法。就认识明白了Quartz的核心原理。<br />&nbsp;<br />2、Quartz虽然很庞大，但是一切都围绕这个核心转，为了配置强大时间调度策略，可以研究专门的CronTrigger。要想灵活配置作业和容器属性，可以通过Quartz的properties文件或者XML来实现。<br />&nbsp;<br />3、要想调度更多的持久化、结构化作业，可以通过数据库读取作业，然后放到容器中执行。<br />&nbsp;<br />4、所有的一切都围绕这个核心原理转，搞明白这个了，再去研究更高级用法就容易多了。<br />&nbsp;<br />5、Quartz与Spring的整合也非常简单，Spring提供一组Bean来支持：MethodInvokingJobDetailFactoryBean、SimpleTriggerBean、SchedulerFactoryBean，看看里面需要注入什么属性即可明白了。Spring会在Spring容器启动时候，启动Quartz容器。<br />&nbsp;<br />6、Quartz容器的关闭方式也很简单，如果是Spring整合，则有两种方法，一种是关闭Spring容器，一种是获取到SchedulerFactoryBean实例，然后调用一个shutdown就搞定了。如果是Quartz独立使用，则直接调用scheduler.shutdown(true);<br />&nbsp;<br />7、Quartz的JobDetail、Trigger都可以在运行时重新设置，并且在下次调用时候起作用。这就为动态作业的实现提供了依据。你可以将调度时间策略存放到数据库，然后通过数据库数据来设定Trigger，这样就能产生动态的调度。<br /><br /><br /><br /><font face="Verdana">http://blog.csdn.net/jiangfeng861016/article/details/5970745</font></p></div><br /><br /><br /><img src ="http://www.blogjava.net/stevenjohn/aggbug/386253.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-08-25 11:48 <a href="http://www.blogjava.net/stevenjohn/archive/2012/08/25/386253.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring Quartz集群</title><link>http://www.blogjava.net/stevenjohn/archive/2012/08/17/385702.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Fri, 17 Aug 2012 10:01:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/08/17/385702.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/385702.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/08/17/385702.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/385702.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/385702.html</trackback:ping><description><![CDATA[<a href="http://blog.sina.com.cn/s/blog_4b0210750100z6jb.html#SinaEditor_Temp_FontName"><span style="text-align: left; widows: 2; text-transform: none; background-color: rgb(248,236,216); text-indent: 0px; font: 12px/20px Verdana, 宋体, sans-serif; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(70,70,70); word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-decorations-in-effect: none; -webkit-text-stroke-width: 0px" class="Apple-style-span"> 
<h2 style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; font-family: 微软雅黑, 黑体; border-top-width: 0px; border-bottom-width: 0px; color: rgb(70,70,70); font-size: 18px; border-left-width: 0px; font-weight: 300; padding-top: 0px" id="t_4b0210750100z6jb" class="titName SG_txta">Spring+Quartz的集群配置</h2><span class="Apple-converted-space">&nbsp;</span></span><br />http://blog.sina.com.cn/s/blog_4b0210750100z6jb.html#SinaEditor_Temp_FontName</a><img src ="http://www.blogjava.net/stevenjohn/aggbug/385702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-08-17 18:01 <a href="http://www.blogjava.net/stevenjohn/archive/2012/08/17/385702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Quartz官网 </title><link>http://www.blogjava.net/stevenjohn/archive/2012/08/17/385667.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Fri, 17 Aug 2012 03:14:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/08/17/385667.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/385667.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/08/17/385667.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/385667.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/385667.html</trackback:ping><description><![CDATA[<p>官网：http://quartz-scheduler.org/</p>
<p>学习文档：http://quartz-scheduler.org/documentation/quartz-2.1.x/tutorials/</p>
<p>例子：http://quartz-scheduler.org/documentation/quartz-2.1.x/examples/&nbsp;</p>
<p>spring集成官网：<a href="http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/scheduling.html#scheduling-quartz">http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/scheduling.html#scheduling-quartz</a><br /></p><br /><br /><a href="http://blog.csdn.net/lan861698789/article/details/7620104">http://blog.csdn.net/lan861698789/article/details/7620104</a> <img src ="http://www.blogjava.net/stevenjohn/aggbug/385667.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-08-17 11:14 <a href="http://www.blogjava.net/stevenjohn/archive/2012/08/17/385667.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>