简单介绍一下俩这得不同,timer是小弟,quartz是大哥。小弟是jdk自带的功能,quartz是一个开源项目。timer能力没有quartz强。
Timer的定义:有且只有一个后台线程对多个业务进程进行定时定频率的调度
先建立一个业务逻辑类,继承timertask,重写他的run方法
package TimerTest;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimerTask;
public class MyTimerTask extends TimerTask {
private String name;
private int count = 0;
MyTimerTask(String inputname){
name = inputname;
}
@Override
public void run() {
if (count<10) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("current exec time is "+sf.format(calendar.getTime()));
// 打印当前name的内容
System.out.println("current name is "+name);
count++;
}else {
cancel();//这个cancel是timetask里面的cancel ----对单体有攻击的技能
System.out.println("Task cancel!");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
然后,建立timer实体类,调用timer.schedule(myTimerTask, 2000l,1000l);等方法实现;
package TimerTest;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import javax.print.CancelablePrintJob;
public class MyTimer {
public static void main(String[] args) {
//1.创建一个timer实例
Timer timer = new Timer();
//2.创建一个mytimertask实例
MyTimerTask myTimerTask = new MyTimerTask("NO.1");
//3.通过timer定时定频率调用timertask的业务逻辑
//第一次执行是当前时间的俩秒后,之后每隔一秒钟执行一次
//timer.schedule(myTimerTask, 2000l,1000l);
/**
* 获取当前时间,并设置当前时间为距离当前时间三秒后的时间
*/
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sf.format(calendar.getTime()));
calendar.add(Calendar.SECOND, 3);
//--schedule的用法------
/**
* 1.在时间等于或超过time的时间执行,且只执行一次
* 俩个参数
*/
//myTimerTask.setName("schedule1");
//timer.schedule(myTimerTask, calendar.getTime());//只执行一次
/**
* 2.时间等于或超过time的时间执行task
* 并且每隔period时间执行一次
* 3个参数
*/
//myTimerTask.setName("schedule2");
//timer.schedule(myTimerTask, calendar.getTime(),3000l);
/**
* 3.等待delay秒后执行且执行一次task
* 2个参数,第二个参数是延迟的秒数,不是具体的时间
*/
//myTimerTask.setName("schedule3");
//timer.schedule(myTimerTask, 1000l);//单位是毫秒
/**
* 4.上面方法的升级版,delay 几秒之后
* 每隔period执行一次
*/
//myTimerTask.setName("schedule4");
//timer.schedule(myTimerTask, 1000l,3000l);
//-----scheduleAtFixedRate------------
/**
* 1. scheduleAtFixedRate(task,time,period)
* task -任务 time -首次执行任务的时间 period -间隔时间
*/
//myTimerTask.setName("scheduleAtFixedRate1");
//timer.scheduleAtFixedRate(myTimerTask, calendar.getTime(), 1000l);
/**
* 2.scheduleAtFixedRate(task,delay,period)
* 看上去和4方法是一摸一样的,其实是有区别的
*/
//myTimerTask.setName("scheduleAtFixedRate2");
//timer.scheduleAtFixedRate(myTimerTask, 1000l, 3000l);
//------------scheduleExectionTime -- 最近发生此任务执行安排的时间,为long型
myTimerTask.setName("test");
timer.schedule(myTimerTask, 4000l);
//打印出4秒钟之后的时间
System.out.println("scheduled time is "+sf.format(myTimerTask.scheduledExecutionTime()));
}
}
关于task中的cancel和timer中的cancel方法,和purge方法的使用
package TimerTest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
public class cancelTest {
public static void main(String[] args) throws InterruptedException {
//创建Timer实例
Timer timer = new Timer();
//创建timertask实例
MyTimerTask task1 = new MyTimerTask("task1");
MyTimerTask task2 = new MyTimerTask("task2");
//获取当前执行时间并打印
Date startTime = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("start time is:"+sf.format(startTime));
//task1首次执行时间是距离当前3秒后执行,之后每隔2秒执行一次
//task2首次执行时间是距离当前1秒后执行,之后每隔2秒执行一次
timer.schedule(task1, 3000l, 2000l);
timer.schedule(task2, 1000l, 2000l);
//使用puge 打印当前已取消的任务数
System.out.println("current canceled task number is "+timer.purge());
//休眠5秒
Thread.sleep(2000);
//截取当前时间并打印
Date cancelTime = new Date();
System.out.println("cancel time is "+sf.format(cancelTime));
//取消所有任务
//cancel 终止计时器丢弃所有当前已安排的任务 群体秒杀的技能
//timer.cancel();
//System.out.println("task all canceled!");
task2.cancel();//task的cancel方法
System.out.println("current canceled task number is "+timer.purge());
}
}
注意:之前说到schedule和scheduleAtFixedRate方法的区别
主要看下面俩个点:
1.首次计划执行时间早于当前时间
schedule如果第一次执行时间被delay了,后面的时间按实际结束时间点计算。
scheduleAtFixedRate如果第一次执行时间被delay了,后面的时间都会按照第一次执行开始的时间计算,为了赶上进度会多次执行任务,因此该方法要考虑同步
//规定时间格式
final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//获取当前的具体时间
Calendar calendar = Calendar.getInstance();
System.out.println("current time is "+sf.format(calendar.getTime()));
//设置成6秒前的时间
calendar.add(Calendar.SECOND, -6);
Timer timer = new Timer();
//第一次执行时间为6秒前,之后秒2秒执行一次
/*timer.schedule(new TimerTask() {
@Override
public void run() {
//打印当前的计划执行时间
System.out.println("schedule exec time is "+sf.format(scheduledExecutionTime()));
System.out.println("task is being exected!");
}
}, calendar.getTime(), 2000l);*/
/* 尽管提前了6秒还是按当前时间计算的
current time is 2017-12-10 22:12:49
schedule exec time is 2017-12-10 22:12:49
task is being exected!
schedule exec time is 2017-12-10 22:12:51
task is being exected!
schedule exec time is 2017-12-10 22:12:53
task is being exected!
*/
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
//打印当前的计划执行时间
System.out.println("scheduleAtFixedRate exec time is "+sf.format(scheduledExecutionTime()));
System.out.println("task is being exected!");
}
}, calendar.getTime(), 2000l);
/* 时间提前了6秒,但是它重复执行了3次,赶工补了一下进度,厉害了!
current time is 2017-12-10 22:22:11
scheduleAtFixedRate exec time is 2017-12-10 22:22:05
task is being exected!
scheduleAtFixedRate exec time is 2017-12-10 22:22:07
task is being exected!
scheduleAtFixedRate exec time is 2017-12-10 22:22:09
task is being exected!
scheduleAtFixedRate exec time is 2017-12-10 22:22:11
task is being exected!
*/
2.任务执行所需时间超出任务时间间隔
schedule下一次执行的时间相当于上一次实际执行完成的时间,因此执行时间会不断延后
scheduleAtFixedRate下一次执行时间相对与上一次开始的时间点,执行时间一般不会延后,存在并发。
/*timer.schedule(new TimerTask() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//打印当前的计划执行时间
System.out.println("schedule exec time is "+sf.format(scheduledExecutionTime()));
System.out.println("task is being exected!");
}
}, calendar.getTime(), 2000l);*/
/* 是基于第一次执行完成后的时间计算的
current time is 2017-12-10 22:32:09
schedule exec time is 2017-12-10 22:32:09
task is being exected!
schedule exec time is 2017-12-10 22:32:12
task is being exected!
schedule exec time is 2017-12-10 22:32:15
task is being exected!
*/
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//打印当前的计划执行时间
System.out.println("schedule exec time is "+sf.format(scheduledExecutionTime()));
System.out.println("task is being exected!");
}
}, calendar.getTime(), 2000l);
/* 并没有延迟,存在并发
current time is 2017-12-10 22:40:37
schedule exec time is 2017-12-10 22:40:37
task is being exected!
schedule exec time is 2017-12-10 22:40:39
task is being exected!
schedule exec time is 2017-12-10 22:40:41
task is being exected!
*/
然后,建立timer实体类,调用timer.schedule(myTimerTask, 2000l,1000l);等方法实现;
Timer有俩个缺陷:
管理并发任务分缺陷:当两个任务同时(我调用上面的两方法时)执行时,都是第一个执行完成后执行第二个操作。
当任务抛出异常是我的缺陷: 当一个timerTask执行一场后,后面的task均会受到影响,无法执行。
一般是不支持使用timer实现定时任务调度,但实际情。。。就这样吧