- schedule(TimerTask task, Date firstTime, long period)
public class Run2_1 {
static public class MyTaskA extends TimerTask {
private int i = 5;
@Override
public void run() {
try {
if (i < 1) return;
System.out.println("A运行了!时间为:" + new Date());
Thread.sleep(i * 1000);
i--;
System.out.println("A结束了!时间为:" + new Date());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyTaskA taskA = new MyTaskA();
Timer timer = new Timer();
Date dateRef = new Date();
timer.schedule(taskA, dateRef, 4000);//period = 4
}
}
输出结果:
A运行了!时间为:Sat Dec 09 08:56:33 CST 2017
A结束了!时间为:Sat Dec 09 08:56:38 CST 2017 //endTime - startTime = 5s > period
A运行了!时间为:Sat Dec 09 08:56:38 CST 2017 //第二次任务立即开始
A结束了!时间为:Sat Dec 09 08:56:42 CST 2017 //endTime - startTime = 4s = period
A运行了!时间为:Sat Dec 09 08:56:42 CST 2017 //第三次任务立即开始
A结束了!时间为:Sat Dec 09 08:56:45 CST 2017 //endTime - startTime = 3s < period
A运行了!时间为:Sat Dec 09 08:56:46 CST 2017 //第四次任务等待 period - (endTime - startTime ) 后开始
A结束了!时间为:Sat Dec 09 08:56:48 CST 2017 //endTime - startTime = 2s < period
A运行了!时间为:Sat Dec 09 08:56:50 CST 2017 //第五次任务等待 period - (endTime - startTime )后开始
A结束了!时间为:Sat Dec 09 08:56:51 CST 2017
归纳:
1. period 是相对上次任务的开始执行时间(startTime)而言的
2. 如果上次任务的执行时间(endTime - startTime)小于period,也即上次任务耗费时间小于间隔,则下次任务需要等待period - endTime 的时间才能开始执行
3. 而如果上次任务的执行时间(endTime - startTime)>= period,也即上次任务耗费时间大于或等于间隔,则下次任务在上次任务执行完成后立即开始执行
- scheduleAtFixedRate(TimerTask task,Date firsttime,long period) 的追赶执行性
public class Run3 {
private static Timer timer = new Timer();
private static int runCount = 0;
static public class MyTask1 extends TimerTask {
@Override
public void run() {
try {
System.out.println("1 begin 运行了!时间为:" + new Date());
Thread.sleep(2000);
System.out.println("1 end 运行了!时间为:" + new Date());
runCount++;
if (runCount == 9) {
timer.cancel();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
MyTask1 task1 = new MyTask1();
Date startDate = new Date();
Thread.sleep(3000);//延时3s
System.out.println("字符串1时间:" + startDate.toLocaleString() + " 当前时间:"
+ new Date().toLocaleString());
//startDate 比当前时间提前3s
timer.scheduleAtFixedRate(task1, startDate, 3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出:
字符串1时间:2017-12-9 12:17:36 当前时间:2017-12-9 12:17:39 执行时间点分析
1 begin 运行了!时间为:Sat Dec 09 12:17:39 CST 2017 - 0
1 end 运行了!时间为:Sat Dec 09 12:17:41 CST 2017 - 2
1 begin 运行了!时间为:Sat Dec 09 12:17:41 CST 2017 - 2 --- 距离上次任务间隔2s
1 end 运行了!时间为:Sat Dec 09 12:17:43 CST 2017 - 4
1 begin 运行了!时间为:Sat Dec 09 12:17:43 CST 2017 - 4 --- 距离上次任务间隔2s
1 end 运行了!时间为:Sat Dec 09 12:17:45 CST 2017 - 6
1 begin 运行了!时间为:Sat Dec 09 12:17:45 CST 2017 - 6 --- 开始恢复正常执行,间隔为3s
1 end 运行了!时间为:Sat Dec 09 12:17:47 CST 2017 - 8
1 begin 运行了!时间为:Sat Dec 09 12:17:48 CST 2017 - 9 --- 距离上次任务间隔3s
1 end 运行了!时间为:Sat Dec 09 12:17:50 CST 2017 - 11
1 begin 运行了!时间为:Sat Dec 09 12:17:51 CST 2017 - 12 --- 距离上次任务间隔3s
1 end 运行了!时间为:Sat Dec 09 12:17:53 CST 2017 - 14
1 begin 运行了!时间为:Sat Dec 09 12:17:54 CST 2017 - 15 --- 距离上次任务间隔3s
1 end 运行了!时间为:Sat Dec 09 12:17:56 CST 2017 - 17
1 begin 运行了!时间为:Sat Dec 09 12:17:57 CST 2017 - 18
1 end 运行了!时间为:Sat Dec 09 12:17:59 CST 2017 - 20
1 begin 运行了!时间为:Sat Dec 09 12:18:00 CST 2017 - 21
1 end 运行了!时间为:Sat Dec 09 12:18:02 CST 2017 - 23
分析:
开始时间比执行时间提前了3秒
可以看到前面三次任务执行间隔都为2s,并不按照设定的延时 3s。此阶段也即为 scheduleAtFixedRate()
方法具有追赶型。他会“补充性”的执行开始时间和当前时间 时间差所对应的任务
再举个栗子:
public class Run3 {
private static Timer timer = new Timer();
private static int runCount = 0;
static public class MyTask1 extends TimerTask {
@Override
public void run() {
System.out.println("1 begin 运行了!时间为:" + new Date());
//Thread.sleep(2000);//不做延时
System.out.println("1 end 运行了!时间为:" + new Date());
runCount++;
if (runCount == 9) {
timer.cancel();
}
}
}
public static void main(String[] args) {
try {
MyTask1 task1 = new MyTask1();
Date startDate = new Date();
Thread.sleep(10000);//延时10s
System.out.println("字符串1时间:" + startDate.toLocaleString() + " 当前时间:"
+ new Date().toLocaleString());
timer.scheduleAtFixedRate(task1, startDate, 3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出:
字符串1时间:2017-12-9 12:39:36 当前时间:2017-12-9 12:39:46
1 begin 运行了!时间为:Sat Dec 09 12:39:46 CST 2017
1 end 运行了!时间为:Sat Dec 09 12:39:46 CST 2017
1 begin 运行了!时间为:Sat Dec 09 12:39:46 CST 2017
1 end 运行了!时间为:Sat Dec 09 12:39:46 CST 2017
1 begin 运行了!时间为:Sat Dec 09 12:39:46 CST 2017
1 end 运行了!时间为:Sat Dec 09 12:39:46 CST 2017
1 begin 运行了!时间为:Sat Dec 09 12:39:46 CST 2017
1 end 运行了!时间为:Sat Dec 09 12:39:46 CST 2017
1 begin 运行了!时间为:Sat Dec 09 12:39:48 CST 2017 --- 开始会恢复正常的时间间隔 3s
1 end 运行了!时间为:Sat Dec 09 12:39:48 CST 2017
1 begin 运行了!时间为:Sat Dec 09 12:39:51 CST 2017
1 end 运行了!时间为:Sat Dec 09 12:39:51 CST 2017
1 begin 运行了!时间为:Sat Dec 09 12:39:54 CST 2017
1 end 运行了!时间为:Sat Dec 09 12:39:54 CST 2017
1 begin 运行了!时间为:Sat Dec 09 12:39:57 CST 2017
1 end 运行了!时间为:Sat Dec 09 12:39:57 CST 2017
1 begin 运行了!时间为:Sat Dec 09 12:40:00 CST 2017
1 end 运行了!时间为:Sat Dec 09 12:40:00 CST 2017
- scheduleAtFixedRate(TimerTask task,Date firsttime,long period) 发生延时
public class Run3 {
private static Timer timer = new Timer();
private static int runCount = 0;
static public class MyTask1 extends TimerTask {
@Override
public void run() {
System.out.println("1 begin 运行了!时间为:" + new Date());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1 end 运行了!时间为:" + new Date());
runCount++;
if (runCount == 5) {
timer.cancel();
}
}
}
public static void main(String[] args) {
MyTask1 task1 = new MyTask1();
Date startDate = new Date();
System.out.println("字符串1时间:" + startDate.toLocaleString() + " 当前时间:"
+ new Date().toLocaleString());
timer.scheduleAtFixedRate(task1, startDate, 3000);
}
}
输出:
字符串1时间:2017-12-10 10:14:59 当前时间:2017-12-10 10:14:59
1 begin 运行了!时间为:Sun Dec 10 10:14:59 CST 2017
1 end 运行了!时间为:Sun Dec 10 10:15:03 CST 2017
1 begin 运行了!时间为:Sun Dec 10 10:15:03 CST 2017
1 end 运行了!时间为:Sun Dec 10 10:15:07 CST 2017
1 begin 运行了!时间为:Sun Dec 10 10:15:07 CST 2017
1 end 运行了!时间为:Sun Dec 10 10:15:11 CST 2017
1 begin 运行了!时间为:Sun Dec 10 10:15:11 CST 2017
1 end 运行了!时间为:Sun Dec 10 10:15:15 CST 2017
1 begin 运行了!时间为:Sun Dec 10 10:15:15 CST 2017
1 end 运行了!时间为:Sun Dec 10 10:15:19 CST 2017
可以看到,但 任务执行时间长与重复间隔 priod 时,则当上次任务执行完毕时,下次任务则跟着立即执行
- scheduleAtFixedRate(TimerTask task,Date firsttime,long period) 不发生延时
public class Run3 {
private static Timer timer = new Timer();
private static int runCount = 0;
static public class MyTask1 extends TimerTask {
@Override
public void run() {
System.out.println("1 begin 运行了!时间为:" + new Date());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1 end 运行了!时间为:" + new Date());
runCount++;
if (runCount == 5) {
timer.cancel();
}
}
}
public static void main(String[] args) {
MyTask1 task1 = new MyTask1();
Date startDate = new Date();
System.out.println("字符串1时间:" + startDate.toLocaleString() + " 当前时间:"
+ new Date().toLocaleString());
timer.scheduleAtFixedRate(task1, startDate, 3000);
}
}
输出:
字符串1时间:2017-12-10 10:16:24 当前时间:2017-12-10 10:16:24
1 begin 运行了!时间为:Sun Dec 10 10:16:24 CST 2017
1 end 运行了!时间为:Sun Dec 10 10:16:26 CST 2017
1 begin 运行了!时间为:Sun Dec 10 10:16:27 CST 2017
1 end 运行了!时间为:Sun Dec 10 10:16:29 CST 2017
1 begin 运行了!时间为:Sun Dec 10 10:16:30 CST 2017
1 end 运行了!时间为:Sun Dec 10 10:16:32 CST 2017
1 begin 运行了!时间为:Sun Dec 10 10:16:33 CST 2017
1 end 运行了!时间为:Sun Dec 10 10:16:35 CST 2017
1 begin 运行了!时间为:Sun Dec 10 10:16:36 CST 2017
1 end 运行了!时间为:Sun Dec 10 10:16:38 CST 2017
可以看到,但任务执行时间小于任务执行间隔 priod时,下次任务的开始执行时间与上次任务的开始执行时间的间隔就是period