Timer 和 TimerTask 定时任务
生活随笔
收集整理的這篇文章主要介紹了
Timer 和 TimerTask 定时任务
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
TimerTask 類
public abstract class TimerTask implements Runnable {/*** 控制訪問timertask內部的鎖*/final Object lock = new Object();/*** 初始狀態為0,就是還沒有被計劃執行*/int state = VIRGIN;/*** 最初始化的狀態*/static final int VIRGIN = 0;/*** 已經被計劃執行了*/static final int SCHEDULED = 1;/*** 正在被執行,反正沒有被返回*/static final int EXECUTED = 2;/*** 已經被返回了,*/static final int CANCELLED = 3;/*** 下次將要被執行的時間*/long nextExecutionTime;/*** 間隔多久執行任務*/long period = 0;/*** 構造函數*/protected TimerTask() {}/*** 會被子類實現,run的內容就是任務的內容*/public abstract void run();/*** 執行返回,如果正在被執行,那么會等執行完畢,再返回*/public boolean cancel() {synchronized(lock) {boolean result = (state == SCHEDULED);state = CANCELLED;return result;}}/*** 返回下一次要被執行的時間*/public long scheduledExecutionTime() {synchronized(lock) {return (period < 0 ? nextExecutionTime + period: nextExecutionTime - period);}} }TaskQueue類源碼
class TaskQueue {/*** 優先級任務對列,隊列初始化的長度為128,這個隊列是一個最小堆* 最小堆就是父節點總是小于等于子節點,這里的大小是任務執行的時刻,任務執行的時刻* 最小的,放在根節點,就是按照先后順序*/private TimerTask[] queue = new TimerTask[128];/*** 優先級對列中的任務數*/private int size = 0;/*** 返回size的值*/int size() {return size;}/*** 向對列添加一個任務*/void add(TimerTask task) {// 如果隊列中任務數要滿的時候,就擴展隊列的長度為2倍if (size + 1 == queue.length)queue = Arrays.copyOf(queue, 2*queue.length);queue[++size] = task; //將任務添加到隊列中fixUp(size); //在隊列末尾插入一個任務后,要重新調整最小堆,以保證最小堆的大小順序}/*** 返回最小堆中的根節點,最小的執行時間的任務*/TimerTask getMin() {return queue[1];}/*** 根據下標i,返回任務*/TimerTask get(int i) {return queue[i];}/*** 刪除最小的任務(根節點),然后將隊列末尾的那個值放在根節點處,再調整堆的順序*/void removeMin() {queue[1] = queue[size];queue[size--] = null; fixDown(1);}/*** 直接刪除第i個節點,然后將隊列末尾的那個節點占據i節點位置,不調整堆的順序*/void quickRemove(int i) {assert i <= size;queue[i] = queue[size];queue[size--] = null; }/*** 設置根節點的執行時間,然后重新調整堆的順序*/void rescheduleMin(long newTime) {queue[1].nextExecutionTime = newTime;fixDown(1);}/*** 判斷任務數是否為0*/boolean isEmpty() {return size==0;}/*** 將這個隊列清空*/void clear() {for (int i=1; i<=size; i++)queue[i] = null;size = 0;}/*** 將K節點從底向上調整堆的順序*/private void fixUp(int k) {while (k > 1) {int j = k >> 1;if (queue[j].nextExecutionTime <= queue[k].nextExecutionTime)break;TimerTask tmp = queue[j]; queue[j] = queue[k]; queue[k] = tmp;k = j;}}/*** 從k節點從上向下調整堆順序*/private void fixDown(int k) {int j;while ((j = k << 1) <= size && j > 0) {if (j < size &&queue[j].nextExecutionTime > queue[j+1].nextExecutionTime)j++; // j indexes smallest kidif (queue[k].nextExecutionTime <= queue[j].nextExecutionTime)break;TimerTask tmp = queue[j]; queue[j] = queue[k]; queue[k] = tmp;k = j;}}/*** 調整一個堆的順序*/void heapify() {for (int i = size/2; i >= 1; i--)fixDown(i);} }?最大堆 ,父節點的值總是大于等于子節點的值。
一個節點的下標,比如 7>>1 就跑到了父節點,6也是。
一個節點的下標,比如 1<<1,就跑到了左子節點2,然后2+1,就跑到了右子節點3。
TimerThread類源碼
class TimerThread extends Thread {/*** true代表隊列中已經沒有任務了,false代表Timer對象的引用已經無效了*/boolean newTasksMayBeScheduled = true;/*** 任務隊列,最小堆*/private TaskQueue queue;TimerThread(TaskQueue queue) { //構造方法this.queue = queue;}public void run() {try {mainLoop();} finally {// Someone killed this Thread, behave as if Timer cancelledsynchronized(queue) {newTasksMayBeScheduled = false;queue.clear(); // Eliminate obsolete references}}}/*** The main timer loop. (See class comment.)*/private void mainLoop() {while (true) {try {TimerTask task;boolean taskFired;synchronized(queue) {// Wait for queue to become non-emptywhile (queue.isEmpty() && newTasksMayBeScheduled)queue.wait();if (queue.isEmpty())break; // Queue is empty and will forever remain; die// Queue nonempty; look at first evt and do the right thinglong currentTime, executionTime;task = queue.getMin();synchronized(task.lock) {if (task.state == TimerTask.CANCELLED) {queue.removeMin();continue; // No action required, poll queue again}currentTime = System.currentTimeMillis();executionTime = task.nextExecutionTime;if (taskFired = (executionTime<=currentTime)) {if (task.period == 0) { // Non-repeating, removequeue.removeMin();task.state = TimerTask.EXECUTED;} else { // Repeating task, reschedulequeue.rescheduleMin(task.period<0 ? currentTime - task.period: executionTime + task.period);}}}if (!taskFired) // Task hasn't yet fired; waitqueue.wait(executionTime - currentTime);}if (taskFired) // Task fired; run it, holding no lockstask.run();} catch(InterruptedException e) {}}} }?
?
?
總結
以上是生活随笔為你收集整理的Timer 和 TimerTask 定时任务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ffmpeg flv转MP4
- 下一篇: 生态 | 南大通用GBase 8a与Su