⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.java

📁 用于移动设备上的java虚拟机源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            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();        }    }    /**     * Terminates this timer, discarding any currently scheduled tasks.     * Does not interfere with a currently executing task (if it exists).     * Once a timer has been terminated, its execution thread terminates     * gracefully, and no more tasks may be scheduled on it.     *     * <p>Note that calling this method from within the run method of a     * timer task that was invoked by this timer absolutely guarantees that     * the ongoing task execution is the last task execution that will ever     * be performed by this timer.     *     * <p>This method may be called repeatedly; the second and subsequent      * calls have no effect.     */    public void cancel() {        synchronized (queue) {	    thread.newTasksMayBeScheduled = false;            queue.clear();            queue.notify();  // In case queue was already empty.        }    }}/** * This "helper class" implements the timer's task execution thread, which * waits for tasks on the timer queue, executions them when they fire, * reschedules repeating tasks, and removes cancelled tasks and spent * non-repeating tasks from the queue. * <p> * The thread will timeout if no TimerTasks are scheduled for it within * a timeout period.  When it times out the thread exits leaving * the newTasksMayBeScheduled * boolean true.  If true and the thread is not alive it should be restarted as * in the Timer.sched method above. */class TimerThread extends Thread {    /**     * This flag is set to false by the reaper to inform us that there     * are no more live references to our Timer object.  Once this flag     * is true and there are no more tasks in our queue, there is no     * work left for us to do, so we terminate gracefully.  Note that     * this field is protected by queue's monitor!     */    boolean newTasksMayBeScheduled = true;    /**     * Our Timer's queue.  We store this reference in preference to     * a reference to the Timer so the reference graph remains acyclic.     * Otherwise, the Timer would never be garbage-collected and this     * thread would never go away.     */    private TaskQueue queue;    /**     * The number of milliseconds to wait after the timer queue is empty     * before the thread exits. It will be restarted when the next TimerTask     * is inserted.     */    private static final long THREAD_TIMEOUT = 30*1000L;    /**     * initialize the timer thread with a task queue.     * @param queue queue of tasks for this timer thread.     */    TimerThread(TaskQueue queue) {        this.queue = queue;    }    /** start the main processing loop.  */    public void run() {        try {            mainLoop();	    /*	     * If mainLoop returns then thread timed out with no events	     * in the queue.  The thread will quietly be restarted in sched()	     * when the next TimerTask is queued.	     */        } catch (Throwable t) {            // Someone killed this Thread, behave as if Timer cancelled            synchronized (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-empty		    // But no more than timeout value.                    while (queue.isEmpty() && newTasksMayBeScheduled) {			queue.wait(THREAD_TIMEOUT);			if (queue.isEmpty()) {			    break;			}                    }                    if (queue.isEmpty())                        break; // Queue is empty and will forever remain; die                    // Queue nonempty; look at first evt and do the right thing                    long 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, remove                                queue.removeMin();                                task.state = TimerTask.EXECUTED;                            } else { // Repeating task, reschedule                                queue.rescheduleMin(                                  task.period < 0 ? currentTime   - task.period                                                : executionTime + task.period);                            }                        }                    }                    if (!taskFired) { // Task hasn't yet fired; wait			queue.wait(executionTime - currentTime);		    }                }                if (taskFired) { // Task fired; run it, holding no locks		    try {			task.run();		    } catch (Exception e) {			// Cancel tasks that cause exceptions			task.cancel();		    }		}            } catch (InterruptedException e) {            }        }    }}/** * This class represents a timer task queue: a priority queue of TimerTasks, * ordered on nextExecutionTime.  Each Timer object has one of these, which it * shares with its TimerThread.  Internally this class uses a heap, which * offers log(n) performance for the add, removeMin and rescheduleMin * operations, and constant time performance for the getMin operation. */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[4];    /**     * The number of tasks in the priority queue.  (The tasks are stored in     * queue[1] up to queue[size]).     */    private int size = 0;    /**     * Adds a new task to the priority queue.     * @param task to add to the current queue     */    void add(TimerTask task) {        // Grow backing store if necessary        if (++size == queue.length) {            TimerTask[] newQueue = new TimerTask[2*queue.length];            System.arraycopy(queue, 0, newQueue, 0, size);            queue = newQueue;        }        queue[size] = task;        fixUp(size);    }    /**     * Return the "head task" of the priority queue.  (The head task is an     * task with the lowest nextExecutionTime.)     * @return the minimum head task of the queue.     */    TimerTask getMin() {        return queue[1];    }    /**     * Remove the head task from the priority queue.     */    void removeMin() {        queue[1] = queue[size];        queue[size--] = null;  // Drop extra reference to prevent memory leak        fixDown(1);    }    /**     * Sets the nextExecutionTime associated with the head task to the      * specified value, and adjusts priority queue accordingly.     * @param newTime new time to apply to head task excution.     */    void rescheduleMin(long newTime) {        queue[1].nextExecutionTime = newTime;        fixDown(1);    }    /**     * Returns true if the priority queue contains no elements.     * @return true if queue is empty.     */    boolean isEmpty() {        return size == 0;    }    /**     * Removes all elements from the priority queue.     */    void clear() {        // Null out task references to prevent memory leak        for (int i = 1; i <= size; i++)            queue[i] = null;        size = 0;    }    /**     * Establishes the heap invariant (described above) assuming the heap     * satisfies the invariant except possibly for the leaf-node indexed by k     * (which may have a nextExecutionTime less than its parent's).     *     * This method functions by "promoting" queue[k] up the hierarchy     * (by swapping it with its parent) repeatedly until queue[k]'s     * nextExecutionTime is greater than or equal to that of its parent.     * @param k index of queued task to be promoted up in the queue.     */    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;        }    }    /**     * Establishes the heap invariant (described above) in the subtree     * rooted at k, which is assumed to satisfy the heap invariant except     * possibly for node k itself (which may have a nextExecutionTime greater     * than its children's).     *     * This method functions by "demoting" queue[k] down the hierarchy     * (by swapping it with its smaller child) repeatedly until queue[k]'s     * nextExecutionTime is less than or equal to those of its children.     * @param k index of queued task to be demoted in the queue.     */    private void fixDown(int k) {        int j;        while ((j = k << 1) <= size) {            if (j < size &&                queue[j].nextExecutionTime > queue[j+1].nextExecutionTime)                j++; // j indexes smallest kid            if (queue[k].nextExecutionTime <= queue[j].nextExecutionTime)                break;            TimerTask tmp = queue[j];  queue[j] = queue[k]; queue[k] = tmp;            k = j;        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -