Timer 和 TimerTask 定时任务
生活随笔
收集整理的這篇文章主要介紹了
Timer 和 TimerTask 定时任务
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?
TimerTask 類
public abstract class TimerTask implements Runnable {/*** 控制訪問timertask內(nèi)部的鎖*/final Object lock = new Object();/*** 初始狀態(tài)為0,就是還沒有被計(jì)劃執(zhí)行*/int state = VIRGIN;/*** 最初始化的狀態(tài)*/static final int VIRGIN = 0;/*** 已經(jīng)被計(jì)劃執(zhí)行了*/static final int SCHEDULED = 1;/*** 正在被執(zhí)行,反正沒有被返回*/static final int EXECUTED = 2;/*** 已經(jīng)被返回了,*/static final int CANCELLED = 3;/*** 下次將要被執(zhí)行的時(shí)間*/long nextExecutionTime;/*** 間隔多久執(zhí)行任務(wù)*/long period = 0;/*** 構(gòu)造函數(shù)*/protected TimerTask() {}/*** 會(huì)被子類實(shí)現(xiàn),run的內(nèi)容就是任務(wù)的內(nèi)容*/public abstract void run();/*** 執(zhí)行返回,如果正在被執(zhí)行,那么會(huì)等執(zhí)行完畢,再返回*/public boolean cancel() {synchronized(lock) {boolean result = (state == SCHEDULED);state = CANCELLED;return result;}}/*** 返回下一次要被執(zhí)行的時(shí)間*/public long scheduledExecutionTime() {synchronized(lock) {return (period < 0 ? nextExecutionTime + period: nextExecutionTime - period);}} }TaskQueue類源碼
class TaskQueue {/*** 優(yōu)先級任務(wù)對列,隊(duì)列初始化的長度為128,這個(gè)隊(duì)列是一個(gè)最小堆* 最小堆就是父節(jié)點(diǎn)總是小于等于子節(jié)點(diǎn),這里的大小是任務(wù)執(zhí)行的時(shí)刻,任務(wù)執(zhí)行的時(shí)刻* 最小的,放在根節(jié)點(diǎn),就是按照先后順序*/private TimerTask[] queue = new TimerTask[128];/*** 優(yōu)先級對列中的任務(wù)數(shù)*/private int size = 0;/*** 返回size的值*/int size() {return size;}/*** 向?qū)α刑砑右粋€(gè)任務(wù)*/void add(TimerTask task) {// 如果隊(duì)列中任務(wù)數(shù)要滿的時(shí)候,就擴(kuò)展隊(duì)列的長度為2倍if (size + 1 == queue.length)queue = Arrays.copyOf(queue, 2*queue.length);queue[++size] = task; //將任務(wù)添加到隊(duì)列中fixUp(size); //在隊(duì)列末尾插入一個(gè)任務(wù)后,要重新調(diào)整最小堆,以保證最小堆的大小順序}/*** 返回最小堆中的根節(jié)點(diǎn),最小的執(zhí)行時(shí)間的任務(wù)*/TimerTask getMin() {return queue[1];}/*** 根據(jù)下標(biāo)i,返回任務(wù)*/TimerTask get(int i) {return queue[i];}/*** 刪除最小的任務(wù)(根節(jié)點(diǎn)),然后將隊(duì)列末尾的那個(gè)值放在根節(jié)點(diǎn)處,再調(diào)整堆的順序*/void removeMin() {queue[1] = queue[size];queue[size--] = null; fixDown(1);}/*** 直接刪除第i個(gè)節(jié)點(diǎn),然后將隊(duì)列末尾的那個(gè)節(jié)點(diǎn)占據(jù)i節(jié)點(diǎn)位置,不調(diào)整堆的順序*/void quickRemove(int i) {assert i <= size;queue[i] = queue[size];queue[size--] = null; }/*** 設(shè)置根節(jié)點(diǎn)的執(zhí)行時(shí)間,然后重新調(diào)整堆的順序*/void rescheduleMin(long newTime) {queue[1].nextExecutionTime = newTime;fixDown(1);}/*** 判斷任務(wù)數(shù)是否為0*/boolean isEmpty() {return size==0;}/*** 將這個(gè)隊(duì)列清空*/void clear() {for (int i=1; i<=size; i++)queue[i] = null;size = 0;}/*** 將K節(jié)點(diǎn)從底向上調(diào)整堆的順序*/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節(jié)點(diǎn)從上向下調(diào)整堆順序*/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;}}/*** 調(diào)整一個(gè)堆的順序*/void heapify() {for (int i = size/2; i >= 1; i--)fixDown(i);} }?最大堆 ,父節(jié)點(diǎn)的值總是大于等于子節(jié)點(diǎn)的值。
一個(gè)節(jié)點(diǎn)的下標(biāo),比如 7>>1 就跑到了父節(jié)點(diǎn),6也是。
一個(gè)節(jié)點(diǎn)的下標(biāo),比如 1<<1,就跑到了左子節(jié)點(diǎn)2,然后2+1,就跑到了右子節(jié)點(diǎn)3。
TimerThread類源碼
class TimerThread extends Thread {/*** true代表隊(duì)列中已經(jīng)沒有任務(wù)了,false代表Timer對象的引用已經(jīng)無效了*/boolean newTasksMayBeScheduled = true;/*** 任務(wù)隊(duì)列,最小堆*/private TaskQueue queue;TimerThread(TaskQueue queue) { //構(gòu)造方法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) {}}} }?
?
?
總結(jié)
以上是生活随笔為你收集整理的Timer 和 TimerTask 定时任务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ffmpeg flv转MP4
- 下一篇: python把excel变成ppt_【转