JAVA隨筆篇一(Timer源碼分析和scheduleAtFixedRate的使用)

來源:互聯網
上載者:User

標籤:java   定時器   timer類   scheduleatfixedrate   

寫完了基礎篇,想了很久要不要去寫進階篇,去寫JSP等等的使用方法,最後決定先不去寫,因為自己並不是JAVA方面的大牛,目前也在邊做邊學,所以決定先將自己不懂的拿出來學並記下來。

Timer是Java內建的java.util.Timer類,通過調度一個java.util.TimerTask任務。這種方式可以讓程式按照某一個頻度執行。


1、Timer類的源碼分析:

public class Timer {    /**     * The timer task queue.  This data structure is shared with the timer     * thread.  The timer produces tasks, via its various schedule calls,     * and the timer thread consumes, executing timer tasks as appropriate,     * and removing them from the queue when they're obsolete.     */    private TaskQueue queue = new TaskQueue();    /**     * The timer thread.     */    private TimerThread thread = new TimerThread(queue);
首先Timer類定義了兩個私人變數TaskQueue和TimerThread。

TaskQueue:Timer類定義了一個定時器任務隊列,一個TimerTasks的優先順序隊列。

class TaskQueue {    /**     * Priority queue represented as a balanced binary heap: the two children     * of queue[n] are queue[2*n] and queue[2*n+1].  The priority queue is     * ordered on the nextExecutionTime field: The TimerTask with the lowest     * nextExecutionTime is in queue[1] (assuming the queue is nonempty).  For     * each node n in the heap, and each descendant of n, d,     * n.nextExecutionTime <= d.nextExecutionTime.     */    private TimerTask[] queue = new TimerTask[128];

TimerThread:Timer類的任務執行線程,從Thread類繼承。以TaskQueue為參數。

在使用Timer類,首先new一個Timer對象,然後利用scheduleXXX函數執行任務,首先分析Timer物件建構過程:

    public Timer() {        this("Timer-" + serialNumber());    }
    public Timer(boolean isDaemon) {        this("Timer-" + serialNumber(), isDaemon);    }<span style="white-space:pre"></span>
    public Timer(String name) {        thread.setName(name);        thread.start();    }
    public Timer(String name, boolean isDaemon) {        thread.setName(name);        thread.setDaemon(isDaemon);        thread.start();    }
可以看出,Timer在構造對象過程中,需要啟動一個TimerThread線程,因此可以猜測,TimerThread線程和Timer對象共同維護一個TaskQueue,利用TaskQueue進行資訊傳遞。

接下來看scheduleXXX函數,所有的scheduleXXX函數都需要調用sched方法,

private void sched(TimerTask task, long time, long period) {        if (time < 0)            throw new IllegalArgumentException("Illegal execution time.");        synchronized(queue) {            if (!thread.newTasksMayBeScheduled)                throw new IllegalStateException("Timer already cancelled.");            synchronized(task.lock) {                if (task.state != TimerTask.VIRGIN)                    throw new IllegalStateException(                        "Task already scheduled or cancelled");                task.nextExecutionTime = time;                task.period = period;                task.state = TimerTask.SCHEDULED;            }            queue.add(task);            if (queue.getMin() == task)                queue.notify();        }    }
這裡首先介紹一下TimerTask類:

public abstract class TimerTask implements Runnable {    /**     * This object is used to control access to the TimerTask internals.     */    final Object lock = new Object();

TimerTask類實現了Runnable介面,待執行的任務置於run()中。在構造定時任務的時候,從TimerTask繼承並實現run方法。並建立任務傳給scheduleXXX方法。

從sched方法中可以看出,sched方法中需要操作TaskQueue隊列,而TimerThread線程啟動之後同樣使用這個隊列,這就必須使用synchronized保證多安全執行緒使用。

2、scheduleXXX的使用:

Timer類的原理很簡單,可以使用的函數不多,下面將全部列出。

(1)void java.util.Timer.schedule(TimerTask task, long delay):多長時間(毫秒)後執行任務

(2)void java.util.Timer.schedule(TimerTask task, Date time):設定某個時間執行任務

(3)void java.util.Timer.schedule(TimerTask task, long delay, long period):delay時間後開始執行任務,並每隔period時間調用任務一次。

(4)void java.util.Timer.schedule(TimerTask task, Date firstTime, long period):第一次在指定firstTime時間點執行任務,之後每隔period時間調用任務一次。

(5)void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period):delay時間後開始執行任務,並每隔period時間調用任務一次。

(6)void java.util.Timer.scheduleAtFixedRate(TimerTask task, Date firstTime, long period):第一次在指定firstTime時間點執行任務,之後每隔period時間調用任務一次。

(7)void java.util.Timer.cancel():終止該Timer

(8)boolean java.util.TimerTask.cancel():終止該TimerTask

這些scheduleXXX方法中,除了(1)(2)外,其他都可以重複調用任務,主要的區別就是schedule和scheduleAtFixedRate的差別。


schedule()方法更注重保持間隔時間的穩定:保障每隔period時間可調用一次。


scheduleAtFixedRate()方法更注重保持執行頻率的穩定:保障多次調用的頻率趨近於period時間,如果某一次調用時間大於period,下一次就會盡量小於period,以保障頻率接近於period


3、Timer類的使用示列

首先建立一個任務:

<pre name="code" class="java">import java.util.TimerTask;public class MyTask extends TimerTask{     private int id;     public MyTask(int id){         this.id = id;     }     public void run(){         System.out.println("線程" + id + ":正在執行");         //System.gc();     }}

main函數代碼:

import java.util.Date;import java.util.Timer;public class Test{    public static void main(String[] args){        Timer timer = new Timer();        timer.schedule(new MyTask(1), 5000);// 5秒後啟動任務        MyTask secondTask = new MyTask(2);        timer.schedule(secondTask, 1000, 3000);        // 1秒後啟動任務,以後每隔3秒執行一次線程        Date date = new Date();        timer.schedule(new MyTask(3), new Date(date.getTime() + 1000));        //      以date為參數,指定某個時間點執行線程        //      timer.cancel();        //      secondTask.cancel();        System.out.println("main thread 結束!");        }}



著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

JAVA隨筆篇一(Timer源碼分析和scheduleAtFixedRate的使用)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.