1. 普通定时器
利用Timer定时器,来完成简单的定时任务
//延迟5秒启动,每隔两秒执行一次
public static void main(String[] args)
{
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("my task is running");
}
}, 5000,2000);
}
2. 多任务的调度(模拟Quartz调度框架)
先创建一个Job的接口,实现一个excute的任务执行的方法
public interface Job
{
public void excute();
}
创建一个Trigger接口,实现一个Boolean类型的方法,根据返回值true或false来调度任务执行
public interface Trigger
{
public boolean Run(long curTime)
}
实现一个QueryJob,模拟数据的查询
public class QueryJob implements Job
{
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Override
public void excute()
{ System.out.println(format.format(new Date())+"数据查询中");
}
}
实现一个每隔N秒执行一次的调度计划
public class ClockTrigger implements Trigger
{
private long startTime; //执行开始时间
private long period; //执行周期
private long preTime = 0;//上一次执行时间
@Override
public boolean canRun(long curTime)
{
if(curTime >= startTime)
{
//第一次执行
if(preTime == 0)
{
preTime = curTime;
return true;
}
//后续执行
else if(preTime + period <= curTime)
{
preTime = curTime;
return true;
}
}
return false;
}
public long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public long getPeriod() {
return period;
}
public void setPeriod(long period) {
this.period = period;
}
}
创建一个调度任务服务,向调度计划Trigge类中传入当前时间,通过Trigger类返回的boolean值来判断当前任务是否执行
public class TimerService
{
private Map<Job,Trigger> jobs;
public TimerService()
{
this.jobs = new HashMap<Job,Trigger>();
}
public void addJob(Job job,Trigger trigger)
{
this.jobs.put(job, trigger);
}
//检查当前的job是否到执行时间
public void schedule()
{
new Timer().schedule(new TimerTask()
{
@Override
public void run() {
long curTime = new Date().getTime();
for(Entry<Job, Trigger>myJob :
jobs.entrySet())
{
Trigger trigger = myJob.getValue();
if(trigger.canRun(curTime))
{
Job job = myJob.getKey();
new Thread(new Runnable() {
@Override
public void run() {
job.execute();
}
}).start();
}
}
}
}, 0,1000);
将任务的执行加入新的线程是为了防止发生阻塞
public static void main(String[] args){
TimerService time = new TimerService();
Job job = new QueryJob();
//设置为当前时间加五秒后执行
Calendar calendar =Calendar.getInstance();
calendar.add(calendar.SECOND,5);
QueryTrigger queryTrigger = new QueryTrigger();
//每隔两秒执行一次
queryTrigger.setPeriod(2000);
queryTrigger.setStartTime(calendar.getTimeInMillis());
time.addJob(job,queryTrigger);
time.schedule();}
Quartz任务调度框架
- 需要导入Quartz的Jar包
先创建一个任务类Job,实现Quartz提供的接口
public class PrintJob implements Job
{
private SimpleDateFormat format = new
SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void execute(JobExecutionContext context) throws JobExecutionException
{
System.out.println(format.format(new Date())+"我打印了");
}
}
SimpleTrigger:一般用于实现每隔一定时间执行任务,以及重复多少次如每 2 小时执行一次,重复执行 5 次。SimpleTrigger 内部实现机制是通过计算间隔时间来计算下次的执行时间,这就导致其不适合调度定时的任务。例如我们想每天的 1:00AM 执行任务,如果使用 SimpleTrigger 的话间隔时间就是一天。注意这里就会有一个问题,即当有 misfired 的任务并且恢复执行时,该执行时间是随机的(取决于何时执行 misfired 的任务,例如某天的 3:00PM)。这会导致之后每天的执行时间都会变成 3:00PM,而不是我们原来期望的 1:00AM。
public class SimpleTriggerDemo
{
public static void main(String[] args) throws
SchedulerException
{
Scheduler scheduler =
StdSchedulerFactory.getDefaultScheduler();
//创建JobDetail实例,并与PprintJob类绑定,通过反射调用Job中的执行方法
JobDetail job = new JobDetail("print","myGroup",PrintJob.class);
Trigger trigger = new
SimpleTrigger("printTrigger",3,2000);
scheduler.scheduleJob(job,trigger);
scheduler.start();
}
}
CronTirgger:利用一个包含 7 个字段的表达式来表示时间调度方式。例如,“0 15 10 * * ? *” 表示每天的 10:15AM 执行任务。对于涉及到星期和月份的调度,CronTirgger 是最适合的,甚至某些情况下是唯一选择。例如,“0 10 14 ? 3 WED” 表示三月份的每个星期三的下午 14:10PM 执行任务。读者可以在具体用到该 trigger 时再详细了解每个字段的含义
public class ConTriggerDemo
{
public static void main(String[] args)
{
Scheduler scheduler = null;
try {
scheduler =
StdSchedulerFactory.getDefaultScheduler();
} catch (SchedulerException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
//创建JobDetail实例,并与PprintJob类绑定,通过反射调用Job中的执行方法
JobDetail job = new
JobDetail("print","myGroup",PrintJob.class);
Trigger trigger =null;
try {
trigger = new CronTrigger("print","myGroup","0/5
* * * * ?");
} catch (ParseException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
try {
scheduler.scheduleJob(job,trigger);
} catch (SchedulerException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
try {
scheduler.start();
} catch (SchedulerException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
CronTirgger表达式规则