方法名稱 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秒,因此就會存在併發性。