天天看点

Java 定时任务及作业调度 Quartz与Timer

相于Quartz的简介可以去网上查查,Timer是JDK中提供的,它们俩个都可以用来做:定时任务,作业调度

最近一个项目要用到这个,所以在网上花了一点时间搜集一下资料。我这里只能做为入门练习,深入的学习要在项目锻炼。

一、Quartz

1.开发作业,要继承org.quartz.Job

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;

/**
 * 作业
 * 
 * @author [email protected] 2012-4-8
 */
public class SimpleJob implements Job {

	public void execute(JobExecutionContext context)
			throws JobExecutionException {
		System.out.println("作业开始:exec...");
		JobKey jobKey = context.getJobDetail().getKey();
		System.out.println(jobKey);
	}
}
           

2.调度

import org.quartz.*;

public class Dispatch {
	public static void main(String[] args) throws Exception {
		// 调度作业
		JobDetail job = JobBuilder.newJob(SimpleJob.class).withIdentity("job1",
				"group1").build();
		// 定时器
		Date runTime = new Date();
		// Date runTime = DateBuilder.nextGivenSecondDate(null, 15);// 启动后15秒运行
		
		// 简单的定时器
		//Trigger trigger = null;
		/*
		trigger = TriggerBuilder.newTrigger()
				.withIdentity("trigger1", "group1").startAt(runTime).build();
		*/
		// 反复执行(5次),指向执行完间隔时间(10秒)
		/*
		trigger = TriggerBuilder.newTrigger()
				.withIdentity("trigger1", "group1").startAt(runTime)
				.withSchedule(
						SimpleScheduleBuilder.simpleSchedule()
								.withIntervalInSeconds(10).withRepeatCount(5))
				.build();
		*/
		//使用cron表达式
		CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(
				"trigger1", "group1").withSchedule(
				CronScheduleBuilder.cronSchedule("0/20 * * * * ?")).build();

		SchedulerFactory sf = new StdSchedulerFactory();
		// Scheduler 调度器 四种状态: stand-by, start, pause, shutdown
		Scheduler sched = sf.getScheduler();
		// 调度器绑定Job 和 Trigger
		Date jobRuningTime = sched.scheduleJob(job, trigger);// 返回Job运行的时间
		System.out.println(new SimpleDateFormat("hh:mm:ss").format(jobRuningTime));
		// 开始调度
		sched.start();

		// sched.shutdown(true);
	}
}
           

3.cron表达式

字段 允许值 允许的特殊字符

秒 0-59 , - * /

分 0-59 , - * /

小时 0-23 , - * /

日期 1-31 , - * ? / L W C

月份 1-12 或者 JAN-DEC , - * /

星期 1-7 或者 SUN-SAT , - * ? / L C #

年(可选) 留空, 1970-2099 , - * /

“*”字符被用来指定所有的值。如:"*"在分钟的字段域里表示“每分钟”。

“?”字符只在日期域和星期域中使用。它被用来指定“非明确的值”。当你需要通过在这两个域中的一个来指定一些东西的时候,它是有用的。看下面的例子你就会明白。

月份中的日期和星期中的日期这两个元素时互斥的一起应该通过设置一个问号来表明不想设置那个字段。

“-”字符被用来指定一个范围。如:“10-12”在小时域意味着“10点、11点、12点”。

“,”字符被用来指定另外的值。如:“MON,WED,FRI”在星期域里表示”星期一、星期三、星期五”。

“/”字符用于指定增量。如:“0/15”在秒域意思是每分钟的0,15,30和45秒。“5/15”在分钟域表示每小时的5,20,35和50。符号“*”在“/”前面(如:*/10)等价于0在“/”前面(如:0/10)。记住一条本质:表达式的每个数值域都是一个有最大值和最小值的集合,如:秒域和分钟域的集合是0-59,日期域是1-31,月份域是1-12。字符“/”可以帮助你在每个字符域中取相应的数值。如:“7/6”在月份域的时候只有当7月的时候才会触发,并不是表示每个6月。

详细用法请见附件

二、Timer

1.作业,要继承java.util.TimerTask

/**
 * 作业
 * 
 * @author [email protected] 2012-4-8
 */
public class TimerTaskJob extends TimerTask {
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	@Override
	public void run() {
		System.out.println("---===+"
				+ sdf.format(Calendar.getInstance().getTime()));
	}
}
           

2.调度

import java.util.Timer;

public class Dispatch {
	public static void main(String[] args) {
		TimerTaskJob job = new TimerTaskJob();
		Timer timer = new Timer();
		// true 说明这个timer以daemon方式运行(优先级低, 程序结束timer也自动结束)只会执行一次
		//timer = new Timer(true);
		timer.schedule(job, 1000, 2000);
		// 几个重载的方法
		// 以指定时间运行
		// 1 timer.schedule(task, time);
		// firstTime为Date类型,period为long 从firstTime时刻开始,每隔period毫秒执行一次。
		// 2 timer.schedule(task, firstTime, period);
		// delay 为long类型:从现在起过delay毫秒执行一次
		// 3 timer.schedule(task, delay)
		// delay为long,period为long:从现在起过delay毫秒以后,每隔period
		// 4 timer.schedule(task, delay, period)
	}
}
           

相于Quartz的高级用法可见附件中的官方提供的例子!!!