本文內容部分引自《Java多線程編程核心技術》,感謝作者!!!
代碼地址:https://github.com/xianzhixianzhixian/thread.git
schedule函數和scheduleAtFixedRate的用法和區別
1、schedule(TimerTask task, Date time)的作用
在指定的時間執行任務,如果指定時間早於當前時間則立即執行任務,如果指定時間晚於當前時間則等待到指定時間再執行任務
2、TimerTask類中的cancel()的作用
TimerTask的cancel()方法cancel()方法作用是將自身從任務隊列中清除,其它任務不受影響
3、Timer類的cancel()的作用
Timer類中的cancel()方法的作用是將任務隊列中的全部任務清空,但是會存在失效的情況,因爲timer.cancel()無法獲得queue的鎖,源碼所示
4、schedule(TimerTask task, long delay)的作用
以當前時間爲參考,在此時間基礎上延遲指定時間的毫秒數後執行一次TimerTask任務
5、schedule(TimerTask task, Date firstTime, long period)的作用
在指定日期之後,按指定的間隔週期性地無限地執行某一任務
6、schedule(TimerTask task,long delay,long period)的作用
以當前時間爲參考,在此時間基礎上延遲指定毫秒數,再以某一時間間隔無限次數地執行某一任務
7、TimerTask是以隊列方式一個一個被順序執行的,並且是線程安全的
8、schedule方法任務延時時:下一次運行開始的時間是上一個任務的結束時間。schedule方法任務不延時時:下一次運行開始的時間是以上一個任務開始的時間加上period時間。scheduleAtFixedRate延時:下一個任務的開始時間是上一個任務的結束時間。scheduleAtFixedRate不延時時:下一個任務的開始時間是上一個任務的結束時間(上一次任務的開始時間加上delay時間,此處delay時間爲run()函數中的Thread.sleep()的時間)。
9、schedule方法不具有追趕性,scheduleAtFixedRate方法具有追趕性。個人理解:不具有追趕性的意思是上一個任務執行完畢後(不延時),下一個任務的開始時間爲上一個任務的開始時間加上period時間,兩個時間段之間的任務被取消了。具有追趕性的意思是上一個任務執行完畢後(不延時),下一個任務的開始時間爲上一個任務的結束時間。
schedule函數和scheduleAtFixedRate的示例
不延遲時
ScheduleNotDelay.java
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* 測試schedule方法任務不延時
* 下一次運行開始的時間是以上一個任務開始的時間加上period時間
* @author: xianzhixianzhixian
* @date: 2019-02-13 22:09
*/
public class ScheduleNotDelay {
private static Timer timer = new Timer();
private static int runCount = 0;
static public class MyTask extends TimerTask {
@Override
public void run() {
try {
System.out.println("1 begin 運行了!時間爲:"+new Date());
Thread.sleep(1000);
System.out.println("1 end 運行了!時間爲:"+new Date());
runCount++;
if (runCount == 5) {
timer.cancel();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
MyTask task = new MyTask();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = "2019-02-13 15:11:00";
Date dateRef = sdf.parse(dateString);
System.out.println("字符串1時間:"+dateRef.toLocaleString()+" 當前時間:"
+new Date().toLocaleString());
timer.schedule(task, dateRef, 4000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
運行結果:schedule方法任務不延時,下一次運行開始的時間是以上一個任務開始的時間加上period時間
ScheduleAtFixedRateNotDelay.java
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* 測試scheduleAtFixedRate不延時
* 下一個任務的開始時間是上一個任務的結束時間(上一次任務的開始時間加上delay時間,此處delay時間爲run()函數中的Thread.sleep()的時間)
* @author: xianzhixianzhixian
* @date: 2019-02-13 22:24
*/
public class ScheduleAtFixedRateNotDelay {
private static Timer timer = new Timer();
private static int runCount = 0;
static public class MyTask extends TimerTask {
@Override
public void run() {
try {
System.out.println("1 begin 運行了!時間爲:"+new Date());
Thread.sleep(1000);
System.out.println("1 end 運行了!時間爲:"+new Date());
runCount++;
if (runCount == 5) {
timer.cancel();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
MyTask task = new MyTask();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = "2019-02-13 22:33:00";
Date dateRef = sdf.parse(dateString);
System.out.println("字符串1時間:"+dateRef.toLocaleString()+" 當前時間:"
+new Date().toLocaleString());
timer.scheduleAtFixedRate(task, dateRef, 4000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
運行結果:scheduleAtFixedRate不延時,下一個任務的開始時間是上一個任務的結束時間(上一次任務的開始時間加上delay時間,此處delay時間爲run()函數中的Thread.sleep()的時間)
延遲時
ScheduleDelay.java
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* 測試schedule方法任務延時
* 下一次運行開始的時間是上一個任務的結束時間
* @author: xianzhixianzhixian
* @date: 2019-02-13 22:18
*/
public class ScheduleDelay {
private static Timer timer = new Timer();
private static int runCount = 0;
static public class MyTask extends TimerTask {
@Override
public void run() {
try {
System.out.println("1 begin 運行了!時間爲:"+new Date());
Thread.sleep(5000);
System.out.println("1 end 運行了!時間爲:"+new Date());
runCount++;
if (runCount == 5) {
timer.cancel();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
MyTask task = new MyTask();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = "2019-02-13 15:11:00";
Date dateRef = sdf.parse(dateString);
System.out.println("字符串1時間:"+dateRef.toLocaleString()+" 當前時間:"
+new Date().toLocaleString());
timer.schedule(task, dateRef, 4000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
運行結果:schedule方法任務延時,下一次運行開始的時間是上一個任務的結束時間
ScheduleAtFixedRateDelay.java
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* 測試scheduleAtFixedRate延時
* 下一個任務的開始時間是上一個任務的結束時間
* @author: xianzhixianzhixian
* @date: 2019-02-13 22:24
*/
public class ScheduleAtFixedRateDelay {
private static Timer timer = new Timer();
private static int runCount = 0;
static public class MyTask extends TimerTask {
@Override
public void run() {
try {
System.out.println("1 begin 運行了!時間爲:"+new Date());
Thread.sleep(5000);
System.out.println("1 end 運行了!時間爲:"+new Date());
runCount++;
if (runCount == 5) {
timer.cancel();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
MyTask task = new MyTask();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = "2019-02-13 15:11:00";
Date dateRef = sdf.parse(dateString);
System.out.println("字符串1時間:"+dateRef.toLocaleString()+" 當前時間:"
+new Date().toLocaleString());
timer.scheduleAtFixedRate(task, dateRef, 4000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
運行結果:scheduleAtFixedRate延時,下一個任務的開始時間是上一個任務的結束時間