1.TimerTask类的cancel()
作用:取消当前TimerTask里的任务
MyTimerTask:
package com.hcx.timer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimerTask;
/**
* Created by HCX on 2017/8/28.
* 需要定时调度的业务逻辑类
*/
public class MyTimerTask extends TimerTask{
private String name;
private Integer count = 0;
public MyTimerTask(String inputName) {
name = inputName;
}
@Override
public void run() {
/*
不希望任务一直不断的重复执行,需求:只执行三次
*/
if(count<3){
/*
* 以yyyy-MM-dd HH:mm:ss的格式打印当前执行时间
* 如:2017-8-29 00:00:00
*/
Calendar calendar = Calendar.getInstance();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current exec time is(task) : " + sf.format(calendar.getTime()));
// 打印当前 name 的内容
System.out.println("Current exec name is(task) : " + name);
count++;
}else {
cancel();
System.out.println("任务取消了");
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
MyTimer:
package com.hcx.timer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
/**
* Created by HCX on 2017/8/28.
* 定时调度类
*/
public class MyTimer {
public static void main(String[] args){
//创建一个Timer实例(位于java.util包下的)
Timer timer = new Timer();
//创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("hcx");
/*
* 通过Timer定时定频率调用MyTimerTask的业务逻辑
* 即第一次执行是在当前时间的两秒钟之后,之后每隔一秒钟执行一次
*/
//timer.schedule(myTimerTask,2000L,1000L);
/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
* 如当前时间是2017-08-29 23:59:57
* 则设置后的时间则为2017-8-30 00:00:00
*/
Calendar calendar = Calendar.getInstance();
// 定义日期格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current exec time is : " + simpleDateFormat.format(calendar.getTime()));
//设置距离当前时间3秒之后的时间
//calendar.add(Calendar.SECOND,3);
/**
* 等待delay毫秒后首次执行task
* 之后每隔period毫秒重复执行一次task
* 如现在是2017-08-30 00:00:00
* 则现在2017-08-30 00:00:03执行一次task:打印任务的名字
* 并且之后每隔两秒会一直不断重复执行下去
*/
myTimerTask.setName("schedule");
timer.schedule(myTimerTask,3000,2000);
/*
执行结果:
Current exec time is : 2017-08-30 10:09:44
Current exec time is(task) : 2017-08-30 10:09:47
Current exec name is(task) : schedule
Current exec time is(task) : 2017-08-30 10:09:49
Current exec name is(task) : schedule
Current exec time is(task) : 2017-08-30 10:09:51
Current exec name is(task) : schedule
任务取消了
*/
}
}
2.TimerTask类的scheduleExecutionTime()
作用: 返回此任务最近实际执行的已安排执行的时间
比如计划的时间是让任务3秒钟之后执行,返回的时间就是距离当前时间3秒钟之后的时间
返回值:最近发生此任务执行安排的时间,为long型
MyTimer:
package com.hcx.timer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
/**
* Created by HCX on 2017/8/28.
* 定时调度类
*/
public class MyTimer {
public static void main(String[] args){
//创建一个Timer实例(位于java.util包下的)
Timer timer = new Timer();
//创建一个MyTimerTask实例
MyTimerTask myTimerTask = new MyTimerTask("hcx");
/*
* 通过Timer定时定频率调用MyTimerTask的业务逻辑
* 即第一次执行是在当前时间的两秒钟之后,之后每隔一秒钟执行一次
*/
//timer.schedule(myTimerTask,2000L,1000L);
/**
* 获取当前时间,并设置成距离当前时间三秒之后的时间
* 如当前时间是2017-08-29 23:59:57
* 则设置后的时间则为2017-8-30 00:00:00
*/
Calendar calendar = Calendar.getInstance();
// 定义日期格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Current exec time is : " + simpleDateFormat.format(calendar.getTime()));
//设置距离当前时间3秒之后的时间
//calendar.add(Calendar.SECOND,3);
/**
* 等待delay毫秒后首次执行task
* 之后每隔period毫秒重复执行一次task
* 如现在是2017-08-30 00:00:00
* 则现在2017-08-30 00:00:03执行一次task:打印任务的名字
* 并且之后每隔两秒会一直不断重复执行下去
*/
myTimerTask.setName("schedule");
timer.schedule(myTimerTask,3000); //只执行一次
System.out.println("schedule time is " + simpleDateFormat.format(myTimerTask.scheduledExecutionTime()));
/*
执行结果:
Current exec time is : 2017-08-30 10:30:54
sche schedule time is 2017-08-30 10:30:57
*/
}
}
3.Timer的cancel()
作用:终止此计时器,丢弃所有当前已安排的任务
CancelTest:
package com.hcx.timer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
/**
* Created by HCX on 2017/8/30.
*/
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 simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("start time is : " + simpleDateFormat.format(startTime));
// task1首次执行是距离现在时间3秒后执行,之后每隔2秒执行一次
// task2首次执行是距离现在时间1秒后执行,之后每隔2秒执行一次
timer.schedule(task1,3000,2000);
timer.schedule(task2,1000,2000);
// 休眠5秒
Thread.sleep(5000);
// 获取当前的执行时间并打印
Date cancelTime = new Date();
System.out.println("cancel time is : " + simpleDateFormat.format(cancelTime));
// 取消所有任务
timer.cancel();
System.out.println("Tasks all canceled!");
/**
* 执行结果:
* start time is : 2017-08-30 10:52:54
Current exec time is(task) : 2017-08-30 10:52:55
Current exec name is(task) : task2
Current exec time is(task) : 2017-08-30 10:52:57
Current exec name is(task) : task1
Current exec time is(task) : 2017-08-30 10:52:57
Current exec name is(task) : task2
cancel time is : 2017-08-30 10:52:59
Tasks all canceled!
*/
}
}
4.Timer的purge()
作用:从此计时器的任务队列中移除所有已取消的任务
例:有两个task在同一个timer下去执行,其中的一个task因为某种原因,被取消了;此时调用purge(),就会将已取消的task从队列中移除,并且会返回一个
返回值:从队列中移除的任务数
CancelTest:
package com.hcx.timer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
/**
* Created by HCX on 2017/8/30.
*/
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 simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("start time is : " + simpleDateFormat.format(startTime));
// task1首次执行是距离现在时间3秒后执行,之后每隔2秒执行一次
// task2首次执行是距离现在时间1秒后执行,之后每隔2秒执行一次
timer.schedule(task1,3000,2000);
timer.schedule(task2,1000,2000);
System.out.println("当前已取消的任务数为 : " + timer.purge());
// 休眠2秒
Thread.sleep(2000);
// 获取当前的执行时间并打印
Date cancelTime = new Date();
System.out.println("cancel time is : " + simpleDateFormat.format(cancelTime));
// 取消task2
task2.cancel();
System.out.println("当前已取消的任务数为 : " + timer.purge());
}
}
运行结果:
start time is : 2017-08-30 11:13:11
当前已取消的任务数为 : 0
Current exec time is(task) : 2017-08-30 11:13:12
Current exec name is(task) : task2
cancel time is : 2017-08-30 11:13:13
当前已取消的任务数为 : 1
Current exec time is(task) : 2017-08-30 11:13:14
Current exec name is(task) : task1
1.首次计划执行的时间早于当前的时间
例如当前的时间为2017-08-30 00:00:05,计划上的第一次执行时间为2017-08-30 00:00:00,时间早于当前的执行时间。
1.schedule方法
“fixed-delay”,如果第一次执行时间被delay了,
随后的执行时间按照上一次实际执行完成的时间点进行计算
2.scheduleAtFixedRate方法
“fixed-rate”,如果第一次执行时间被delay了(第一次执行的时间早于现在的时间),
随后的执行时间按照上一次开始的时间点进行计算,
并且为了赶上进度会多次执行任务,因此TimerTask中的执行体需要考虑同步
代码演示schedule方法:
package com.hcx.timer2;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by HCX on 2017/8/30.
*/
public class DifferenceTest {
public static void main(String[] args){
// 定义时间格式
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秒前的时间,若当前时间为2017-08-30 00:00:06·
// 那么设置之后时间变成2017-08-30 00:00:00
calendar.add(Calendar.SECOND,-6);
Timer timer = new Timer();
// 第一次执行时间为6秒前,之后每隔两秒钟执行一次
//使用内部类定义重写run方法,就不需要单独建一个业务调度逻辑类了
timer.schedule(new TimerTask() {
public void run() {
// 打印当前的计划执行时间
System.out.println("Schedule exec time is : " + sf.format(scheduledExecutionTime()));
//scheduledExecutionTime():获取TimerTask最近的一次计划执行时间 sf.format(scheduledExecutionTime()));
System.out.println("任务正在执行");
}
}, calendar.getTime(), 2000);
}
}
执行结果:
Current time is : 2017-09-04 11:41:03
Schedule exec time is : 2017-09-04 11:41:03
任务正在执行
Schedule exec time is : 2017-09-04 11:41:05
任务正在执行
Schedule exec time is : 2017-09-04 11:41:07
任务正在执行
Schedule exec time is : 2017-09-04 11:41:09
任务正在执行
...
scheduleAtFixedRate方法:
package com.hcx.timer2;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by HCX on 2017/8/30.
*/
public class DifferenceTest {
public static void main(String[] args){
// 定义时间格式
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秒前的时间,若当前时间为2017-08-30 00:00:06·
// 那么设置之后时间变成2017-08-30 00:00:00
calendar.add(Calendar.SECOND,-6);
Timer timer = new Timer();
// 第一次执行时间为6秒前,之后每隔两秒钟执行一次
//使用内部类定义重写run方法,就不需要单独建一个业务调度逻辑类了
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
// 打印当前的计划执行时间
System.out.println("Schedule exec time is : " + sf.format(scheduledExecutionTime()));
//scheduledExecutionTime():获取TimerTask最近的一次计划执行时间 sf.format(scheduledExecutionTime()));
System.out.println("任务正在执行");
}
}, calendar.getTime(), 2000);
}
}
执行结果:
Current time is : 2017-09-04 11:50:36
Schedule exec time is : 2017-09-04 11:50:30
任务正在执行
Schedule exec time is : 2017-09-04 11:50:32
任务正在执行
Schedule exec time is : 2017-09-04 11:50:34
任务正在执行
Schedule exec time is : 2017-09-04 11:50:36
任务正在执行
Schedule exec time is : 2017-09-04 11:50:38
任务正在执行
Schedule exec time is : 2017-09-04 11:50:40
任务正在执行
Schedule exec time is : 2017-09-04 11:50:42
任务正在执行
...
2.任务执行所需时间超出任务的执行周期间隔
例如任务需要每隔2秒都执行一次,但是单次完成任务的时间需要3秒,此时就超出了任务执行的周期间隔。
1. schedule方法
下一次执行时间相对于上一次实际执行完成的时间点,因此执行时间会不断延后
2.scheduleAtFixedRate方法
下一次执行时间相对于上一次开始的时间点,因此执行时间一般不会延后,因此存在并发性
代码演示schedule方法:
package com.hcx.timer2;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by HCX on 2017/8/30.
*/
public class DifferenceTest {
public static void main(String[] args){
// 定义时间格式
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()));
Timer timer = new Timer();
// 第一次执行时间为6秒前,之后每隔两秒钟执行一次
//使用内部类定义重写run方法,就不需要单独建一个业务调度逻辑类了
timer.schedule(new TimerTask() {
public void run() {
try{
Thread.sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}
// 打印当前的计划执行时间
System.out.println("Schedule exec time is : " + sf.format(scheduledExecutionTime()));
//scheduledExecutionTime():获取TimerTask最近的一次计划执行时间 sf.format(scheduledExecutionTime()));
System.out.println("任务正在执行");
}
}, calendar.getTime(), 2000);
}
}
运行结果:
Current time is : 2017-09-04 14:30:51
Schedule exec time is : 2017-09-04 14:30:51
任务正在执行
Schedule exec time is : 2017-09-04 14:30:54
任务正在执行
Schedule exec time is : 2017-09-04 14:30:57
任务正在执行
Schedule exec time is : 2017-09-04 14:31:00
任务正在执行
Schedule exec time is : 2017-09-04 14:31:03
任务正在执行
...
代码演示scheduleAtFixedRate方法:
package com.hcx.timer2;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by HCX on 2017/8/30.
*/
public class DifferenceTest {
public static void main(String[] args){
// 定义时间格式
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()));
Timer timer = new Timer();
// 第一次执行时间为6秒前,之后每隔两秒钟执行一次
//使用内部类定义重写run方法,就不需要单独建一个业务调度逻辑类了
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
try{
Thread.sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}
// 打印当前的计划执行时间
System.out.println("Schedule exec time is : " + sf.format(scheduledExecutionTime()));
//scheduledExecutionTime():获取TimerTask最近的一次计划执行时间 sf.format(scheduledExecutionTime()));
System.out.println("任务正在执行");
}
}, calendar.getTime(), 2000);
}
}
执行结果:
Current time is : 2017-09-04 14:34:21
Schedule exec time is : 2017-09-04 14:34:21
任务正在执行
Schedule exec time is : 2017-09-04 14:34:23
任务正在执行
Schedule exec time is : 2017-09-04 14:34:25
任务正在执行
Schedule exec time is : 2017-09-04 14:34:27
任务正在执行
...