简单作业:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
package
quartz_project.example2;
import
java.util.Date;
import
org.quartz.Job;
import
org.quartz.JobExecutionContext;
import
org.quartz.JobExecutionException;
import
org.quartz.JobKey;
import
org.slf4j.Logger;
import
org.slf4j.LoggerFactory;
/**
* 需要在特定的日期或者时间启动,
* 并且期望以一个可能的间隔时间重复执行 n 次的Job
*
* @author caijw
*/
public
class
SimpleJob
implements
Job {
private
static
Logger _log = LoggerFactory.getLogger(SimpleJob.
class
);
@Override
public
void
execute(JobExecutionContext ctx)
throws
JobExecutionException {
JobKey jobKey = ctx.getJobDetail().getKey();
_log.info(
"SimpleJob says: "
+ jobKey +
" executing at "
+
new
Date());
}
}
|
注:由于代码较长,本文将按照任务分开解释,第一段代码将做为下列任务的运行环境。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Logger log = LoggerFactory.getLogger(SimpleTriggerExample.
class
);
log.info(
"----- Initializing --------"
);
//第一步我们必须获取一个调度器
SchedulerFactory sf =
new
StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
log.info(
"----- Initialization complete -------"
);
//作业的执行时间(这里需要注意,下面详细说明)
Date startTime = DateBuilder.nextGivenSecondDate(
null
,
15
);
log.info(
"----- scheduling jobs --------"
);
|
注意:Date startTime = DateBuilder.nextGivenSecondDate(null, 15);
每分钟以15秒为单位,在当前时间的在下一个15秒开始。例如:当前时间为18:20:02秒,那么作业将在18:20:15秒执行。
一、在startTime时间点执行job1
1
2
3
4
5
6
7
8
9
10
11
12
13
|
JobDetail job = JobBuilder.newJob(SimpleJob.
class
)
.withIdentity(
"job1"
,
"group1"
)
.build();
SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
.withIdentity(
"trigger1"
,
"group1"
)
.startAt(startTime).build();
//该触发器将在startTime时执行作业
Date ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() +
" will run at: "
+ ft +
" and repeat: "
+ trigger.getRepeatCount() +
" times, every "
+ trigger.getRepeatInterval() /
1000
+
" seconds"
);
|
二、在startTime时间点执行job2
1
2
3
4
5
6
7
8
9
10
11
12
|
job = JobBuilder.newJob(SimpleJob.
class
)
.withIdentity(
"job2"
,
"group1"
)
.build();
trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
.withIdentity(
"trigger2"
,
"group1"
)
.startAt(startTime).build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() +
" will run at: "
+ ft +
" and repeat: "
+ trigger.getRepeatCount() +
" times, every "
+ trigger.getRepeatInterval() /
1000
+
" seconds"
);
|
通过下面的输出结果可以发现:该作业是以多线程并发运行的。
1
2
3
4
5
|
[INFO] 27 一月 09:19:15.000 下午 DefaultQuartzScheduler_Worker-2 [quartz_project.example2.SimpleJob]
SimpleJob says: group1.job1 executing at Mon Jan 27 21:19:15 CST 2014
[INFO] 27 一月 09:19:15.000 下午 DefaultQuartzScheduler_Worker-3 [quartz_project.example2.SimpleJob]
SimpleJob says: group1.job2 executing at Mon Jan 27 21:19:15 CST 2014
|
三、在startTime时间点执行job3,以后每隔10s运行一次,重复10次,共运行11次。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
job = JobBuilder.newJob(SimpleJob.
class
)
.withIdentity(
"job3"
,
"group1"
)
.build();
trigger = TriggerBuilder.newTrigger()
.withIdentity(
"trigger3"
,
"group1"
)
.startAt(startTime)
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(
10
)
//时间间隔10s
.withRepeatCount(
10
))
//重复次数10次
.forJob(job).build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() +
" will run at: "
+ ft +
" and repeat: "
+ trigger.getRepeatCount() +
" times, every "
+ trigger.getRepeatInterval() /
1000
+
" seconds"
);
|
三、为job3重新绑定trigger,在startTime时间点执行job3,以后每隔10s运行一次,重复2次。
1
2
3
4
5
6
7
8
9
10
11
|
trigger = TriggerBuilder.newTrigger()
.withIdentity(
"trigger3"
,
"group2"
)
//记得换成group2不然就不唯一了
.startAt(startTime)
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(
10
)
.withRepeatCount(
2
))
.forJob(job).build();
ft = sched.scheduleJob(trigger);
//注意这里,不可以使用sched.scheduleJob(job, trigger)
log.info(job.getKey() +
" will [also] run at: "
+ ft +
" and repeat: "
+ trigger.getRepeatCount() +
" times, every "
+ trigger.getRepeatInterval() /
1000
+
" seconds"
);
|
四、在当前时间的5分钟后执行job5。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
job = JobBuilder.newJob(SimpleJob.
class
)
.withIdentity(
"job5"
,
"group1"
)
.build();
trigger = (SimpleTrigger) TriggerBuilder.newTrigger()
.withIdentity(
"trigger5"
,
"group1"
)
.startAt(DateBuilder.futureDate(
5
, IntervalUnit.MINUTE))
//当前时间的5分钟后
.build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() +
" will run at: "
+ ft +
" and repeat: "
+ trigger.getRepeatCount() +
" times, every "
+ trigger.getRepeatInterval() /
1000
+
" seconds"
);
|
五、在startTime时间点执行job6,以后每隔40s运行一次,无限执行下去。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
job = JobBuilder.newJob(SimpleJob.
class
)
.withIdentity(
"job6"
,
"group1"
)
.build();
trigger = TriggerBuilder.newTrigger()
.withIdentity(
"trigger6"
,
"group1"
)
.startAt(startTime)
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(
40
)
.repeatForever())
//无限次
.forJob(job).build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() +
" will run at: "
+ ft +
" and repeat: "
+ trigger.getRepeatCount() +
" times, every "
+ trigger.getRepeatInterval() /
1000
+
" seconds"
);
|
六、所有的作业都被加到了调度器中,但是只有调度器启动作业才会开始执行
1
2
3
|
log.info(
"------ starting scheduler -------"
);
sched.start();
//启动调度器
log.info(
"------ started scheduler -------"
);
|
七、在调度器启动后,仍可以添加作业进去:在startTime时间点执行job7,以后每隔5分钟运行一次,执行20次。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
job = JobBuilder.newJob(SimpleJob.
class
)
.withIdentity(
"job7"
,
"group1"
)
.build();
trigger = TriggerBuilder.newTrigger()
.withIdentity(
"trigger7"
,
"group1"
)
.startAt(startTime)
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMinutes(
5
)
.withRepeatCount(
20
))
.build();
ft = sched.scheduleJob(job, trigger);
log.info(job.getKey() +
" will run at: "
+ ft +
" and repeat: "
+ trigger.getRepeatCount() +
" times, every "
+ trigger.getRepeatInterval() /
1000
+
" seconds"
);
|
八、作业可以不需要触发器,而是通过手动启动。
1
2
3
4
5
6
7
8
9
|
job = JobBuilder.newJob(SimpleJob.
class
)
.withIdentity(
"job8"
,
"group1"
)
.storeDurably()
//即使没有Trigger关联时,也不需要删除该JobDetail
.build();
sched.addJob(job,
true
);
log.info(
"'Manually' triggering job8..."
);
sched.triggerJob(JobKey.jobKey(
"job8"
,
"group1"
));
//通过手动触发,执行作业8
|
九、重新注册job7,利用线程休眠模拟过了执行时间,效果就是该作业会马上执行一次。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
log.info(
"------- Waiting 30 seconds... --------------"
);
try
{
Thread.sleep(30L * 1000L);
}
catch
(Exception e) {
log.error(e.getMessage(), e);
}
log.info(
"---------- rescheduling... -------"
);
trigger = TriggerBuilder.newTrigger()
.withIdentity(
"trigger7"
,
"group1"
)
.startAt(startTime)
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInMinutes(
5
)
.withRepeatCount(
20
))
.build();
ft = sched.rescheduleJob(trigger.getKey(), trigger);
log.info(
"job7 rescheduled to run at: "
+ ft);
|
注意: ft = sched.rescheduleJob(trigger.getKey(), trigger); 表示在sched.start()之后调用,可以在job开始后重新定义trigger,然后重新注册。
十、五分钟后关闭调度器,所以没有执行完的作业将终止。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
log.info(
"------- Waiting five minutes... ------------"
);
try
{
// wait five minutes to show jobs
Thread.sleep(300L * 1000L);
// executing...
}
catch
(Exception e) {
}
log.info(
"------- Shutting Down ---------------------"
);
sched.shutdown(
true
);
log.info(
"------- Shutdown Complete -----------------"
);
|
十一、查看这段时间内,总执行了多少任务。
1
2
|
SchedulerMetaData metaData = sched.getMetaData();
log.info(
"Executed "
+ metaData.getNumberOfJobsExecuted() +
" jobs."
);
|