方法名称 schedule() 和 scheduleAtFixedRate() 的区别
两种情况看区别
- 首次计划执行的时间早于当前时间
比如说:当前时间是 11:06
, 但是首次计划执行的时间应该为: 11:00
- 任务执行所需的时间超出任务的执行周期间隔
比如说:我们执行的任务的时间为 3秒
,但是任务执行的周期间隔为 2秒
。
详细分析
首次计划的时间早于当前时间
schedule 方法
fixed-delay
; 如果第一次执行的时间被 delay
了,随后的执行时间按照上一次实际执行完成的时间
点进行计算。
代码实例
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
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秒之前的时间
calendar.add(Calendar.SECOND, -6);
System.out.println("current time minus six second is :"+ sf.format(calendar.getTime()));
System.out.println("Task is being executed!");
// 使用 timer 来执行
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("scheduled exec time is :"+ sf.format(scheduledExecutionTime()));
}
}, calendar.getTime(), 2000);
}
}
控制台输出
current time is:2018-07-05 13:09:57
current time minus six second is :2018-07-05 13:09:51
scheduled exec time is :2018-07-05 13:09:57
scheduled exec time is :2018-07-05 13:09:59
scheduled exec time is :2018-07-05 13:10:01
scheduled exec time is :2018-07-05 13:10:03
scheduled exec time is :2018-07-05 13:10:05
scheduled exec time is :2018-07-05 13:10:07
scheduled exec time is :2018-07-05 13:10:09
schedule 方法总结
虽然我们是将事件提前了6秒,但是使用 schedule
还是从当前时间开始执行。然后每隔两秒执行一次。
scheduleAtFixedRate 方法
fixed-rate
; 如果第一次执行时间被 delay
了,随后的执行时间按照上一次开始的点
计算,并且为了赶上进度
会多次执行任务,因为 TimerTask
中的执行需要考虑同步
。
代码实例
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
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秒之前的时间
calendar.add(Calendar.SECOND, -6);
System.out.println("current time minus six second is :"+ sf.format(calendar.getTime()));
// 使用 timer 来执行
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("scheduled exec time is :"+ sf.format(scheduledExecutionTime()));
}
}, calendar.getTime(), 2000);
}
}
控制台输出
current time is:2018-07-06 14:32:34
current time minus six second is :2018-07-06 14:32:28
scheduled exec time is :2018-07-06 14:32:28
scheduled exec time is :2018-07-06 14:32:30
scheduled exec time is :2018-07-06 14:32:32
scheduled exec time is :2018-07-06 14:32:34
scheduled exec time is :2018-07-06 14:32:36
scheduled exec time is :2018-07-06 14:32:38
scheduleAtFixedRate 方法总结
我们可以看到实际的效果是:在启动执行的时候,会立马执行3次
,就是为了追赶已经过去的6秒。然后再按照设定的间隔,每两秒钟执行一次。
任务执行所需的时间超出任务的执行周期间隔
schedule 方法
下次执行时间相当于上一次实际执行完成的时间点,因为执行的时间会不断延后。
代码实例
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
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 timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// 模拟当前执行的过程需要 3秒
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 打印最近一次执行的时间
System.out.println("scheduled exec time is :"+ sf.format(scheduledExecutionTime()));
}
}, calendar.getTime(), 2000);
}
}
控制台输出
current time is:2018-07-06 14:43:51
scheduled exec time is :2018-07-06 14:43:51
scheduled exec time is :2018-07-06 14:43:54
scheduled exec time is :2018-07-06 14:43:57
scheduled exec time is :2018-07-06 14:44:00
scheduled exec time is :2018-07-06 14:44:03
说明
我们可以空控制台中输出的结果中看到:我们当前的时间为 14:43:51,然后第一次计划执行的时间也为 14:43:51。但是以后每次执行的时间都是相隔 3秒钟,并不是我们上面设置 timerTask 的时间间隔 2秒。所以说使用 schedule 方法,在这种情况下会不断的延后。
scheduleAtFixedRate 方法
下一次执行时间相对于上一次开始的时间点
,因此执行时间一般不会延后
,因此存在并发性
代码实例
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
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 timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// 模拟当前执行的过程需要 3秒
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 打印最近一次执行的时间
System.out.println("scheduled exec time is :"+ sf.format(scheduledExecutionTime()));
}
}, calendar.getTime(), 2000);
}
}
控制台输出
current time is:2018-07-07 10:15:51
scheduled exec time is :2018-07-07 10:15:51
scheduled exec time is :2018-07-07 10:15:53
scheduled exec time is :2018-07-07 10:15:55
scheduled exec time is :2018-07-07 10:15:57
scheduled exec time is :2018-07-07 10:15:59
说明
当执行的频率为2秒钟,但是执行的时间为3秒的时。我们从控制台上的输出可以看到,执行的频率还是为2秒,因此就会存在并发性。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。