Java多線程問題--schedule函數和scheduleAtFixedRate的用法和區別

本文內容部分引自《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延時,下一個任務的開始時間是上一個任務的結束時間

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章