Timer是java自带的定时器,可以做一些简单的定时任务。
创建对象
Timer timer = new Timer();
//定义定时器的名字
Timer timer1 = new Timer("定时器1");
//第一个参数:定时器名字,第二参数设置是否是守护线程
Timer timer2 = new Timer("定时器2", true);
定时器其实就是另起线程执行指定的task,所以这里可以设置是否是守护线程,当主线程挂了,定时器的任务也会结束。
TimerTask
TimerTask是一个实现了Runable的类,代表的是一个定时任务,一个Timer定时器可以有多个定时任务TimerTask同时执行,
TimerTask是一个抽象类,要创建Task任务可以继承TimerTask或者用匿名类创建;
延时任务schedule
- 1.指定延时时长
Timer timer = new Timer();
TimerTask task = new TimerTask(){
@Override
public void run() {
System.out.println(new Date());
}
};
System.out.println(new Date());
timer.schedule(task,5000); //5秒钟后执行task任务
输出为:
Sun Jun 10 15:10:31 CST 2018
Sun Jun 10 15:10:36 CST 2018
- 2.指定时间
Timer timer = new Timer();
TimerTask task = new TimerTask(){
@Override
public void run() {
System.out.println(new Date());
}
};
System.out.println(new Date());
//时间是10秒钟后的时间
timer.schedule(task,new Date(new Date().getTime()+10000));
输出是:
Sun Jun 10 15:29:05 CST 2018
Sun Jun 10 15:29:15 CST 2018
周期任务schedule
Timer timer = new Timer();
TimerTask task = new TimerTask(){
@Override
public void run() {
System.out.println(new Date());
}
};
System.out.println(new Date());
timer.schedule(task,5000,1000); //5秒后执行,周期是1s
输出是:
Sun Jun 10 15:36:55 CST 2018
Sun Jun 10 15:37:00 CST 2018
Sun Jun 10 15:37:01 CST 2018
Sun Jun 10 15:37:02 CST 2018
Sun Jun 10 15:37:03 CST 2018
Sun Jun 10 15:37:04 CST 2018
Sun Jun 10 15:37:05 CST 2018
…………………
可以看到任务是5秒钟后每过1s打印1次,
和上面的延时任务一样,第二个参数也可以指定时间。
scheduleAtFixedRate和schedule的区别
两者之间的区别在于对于过时时间任务的处理:
schedule:
Timer timer = new Timer();
TimerTask task = new TimerTask(){
@Override
public void run() {
System.out.println(new Date());
}
};
System.out.println(new Date());
//当前时间的5秒钟之前的时间
timer.schedule(task,new Date(new Date().getTime()-5000),1000);
输出:
Sun Jun 10 15:57:12 CST 2018
Sun Jun 10 15:57:12 CST 2018
Sun Jun 10 15:57:13 CST 2018
Sun Jun 10 15:57:14 CST 2018
Sun Jun 10 15:57:15 CST 2018
………………………………………..
会直接快速输出,并且以当前时间为开始时间进行周期任务
scheduleAtFixedRate:
Timer timer = new Timer();
TimerTask task = new TimerTask(){
@Override
public void run() {
System.out.println(new Date());
}
};
System.out.println(new Date());
timer.scheduleAtFixedRate(task,new Date(new Date().getTime()-5000),1000);
和上面一样的代码,只是调用的方法改成了scheduleAtFixedRate,输出为:
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:55 CST 2018
Sun Jun 10 15:59:56 CST 2018
Sun Jun 10 15:59:57 CST 2018
Sun Jun 10 15:59:58 CST 2018
…………………………………..
输出还是以当前时间为起始点,但是会把之前的任务执行完。在追赶上正常的时间前,周期不是指定的周期,而是尽可能快速的把之前发任务执行完。
取消任务
- 指定取消:
Timer timer = new Timer();
TimerTask task1 = new TimerTask(){
@Override
public void run() {
System.out.println("task1:"+new Date());
}
};
TimerTask task2 = new TimerTask(){
@Override
public void run() {
System.out.println("task2:"+new Date());
}
};
System.out.println("start:" + new Date());
timer.schedule(task1,2000,1000); //3秒钟后执行,周期为1s
timer.schedule(task2,3000,1000);
Thread.sleep(6000); //主线程暂停6s,再取消task1任务
System.out.println("取消task1任务");
task1.cancel();
输出为:
start:Sun Jun 10 16:11:44 CST 2018
task1:Sun Jun 10 16:11:46 CST 2018
task2:Sun Jun 10 16:11:47 CST 2018
task1:Sun Jun 10 16:11:47 CST 2018
task2:Sun Jun 10 16:11:48 CST 2018
task1:Sun Jun 10 16:11:48 CST 2018
task2:Sun Jun 10 16:11:49 CST 2018
task1:Sun Jun 10 16:11:49 CST 2018
取消task1任务
task2:Sun Jun 10 16:11:50 CST 2018
task2:Sun Jun 10 16:11:51 CST 2018
task2:Sun Jun 10 16:11:52 CST 2018
task2:Sun Jun 10 16:11:53 CST 2018
…………………………………………………
可以看到再取消task1后,task1的任务不再执行.
取消全部任务
Timer timer = new Timer();
TimerTask task1 = new TimerTask(){
@Override
public void run() {
System.out.println("task1:"+new Date());
}
};
TimerTask task2 = new TimerTask(){
@Override
public void run() {
System.out.println("task2:"+new Date());
}
};
System.out.println("start:" + new Date());
timer.schedule(task1,2000,1000);
timer.schedule(task2,3000,1000);
Thread.sleep(8000);
System.out.println("取消全部任务");
timer.cancel();
输出为:
start:Sun Jun 10 16:13:24 CST 2018
task1:Sun Jun 10 16:13:26 CST 2018
task1:Sun Jun 10 16:13:27 CST 2018
task2:Sun Jun 10 16:13:27 CST 2018
task2:Sun Jun 10 16:13:28 CST 2018
task1:Sun Jun 10 16:13:28 CST 2018
task1:Sun Jun 10 16:13:29 CST 2018
task2:Sun Jun 10 16:13:29 CST 2018
task2:Sun Jun 10 16:13:30 CST 2018
task1:Sun Jun 10 16:13:30 CST 2018
task1:Sun Jun 10 16:13:31 CST 2018
task2:Sun Jun 10 16:13:31 CST 2018
取消全部任务
用定时器调用cancel后,定时器内的全部任务都会被取消
守护线程定时器
Timer timer = new Timer(true);
TimerTask task1 = new TimerTask(){
@Override
public void run() {
System.out.println("task:"+new Date());
}
};
System.out.println("start:" + new Date());
timer.schedule(task1,2000,1000);
Thread.sleep(5000);
输出为:
start:Sun Jun 10 16:19:10 CST 2018
task:Sun Jun 10 16:19:12 CST 2018
task:Sun Jun 10 16:19:13 CST 2018
task:Sun Jun 10 16:19:14 CST 2018
main线程休眠5秒钟后会退出进入dead,所以守护线程定时器也会被强制结束,如果不是守护线程,task会一直执行下去。关于线程方面的可参考入坑JAVA多线程并发(二)线程的生命周期和常用方法。