Timer.java revision 2362
2362N/A * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * A facility for threads to schedule tasks for future execution in a 0N/A * background thread. Tasks may be scheduled for one-time execution, or for 0N/A * repeated execution at regular intervals. 0N/A * <p>Corresponding to each <tt>Timer</tt> object is a single background 0N/A * thread that is used to execute all of the timer's tasks, sequentially. 0N/A * Timer tasks should complete quickly. If a timer task takes excessive time 0N/A * to complete, it "hogs" the timer's task execution thread. This can, in 0N/A * turn, delay the execution of subsequent tasks, which may "bunch up" and 0N/A * execute in rapid succession when (and if) the offending task finally 0N/A * <p>After the last live reference to a <tt>Timer</tt> object goes away 0N/A * <i>and</i> all outstanding tasks have completed execution, the timer's task 0N/A * execution thread terminates gracefully (and becomes subject to garbage 0N/A * collection). However, this can take arbitrarily long to occur. By 0N/A * default, the task execution thread does not run as a <i>daemon thread</i>, 0N/A * so it is capable of keeping an application from terminating. If a caller 0N/A * wants to terminate a timer's task execution thread rapidly, the caller 0N/A * should invoke the timer's <tt>cancel</tt> method. 0N/A * <p>If the timer's task execution thread terminates unexpectedly, for 0N/A * example, because its <tt>stop</tt> method is invoked, any further 0N/A * attempt to schedule a task on the timer will result in an 0N/A * <tt>IllegalStateException</tt>, as if the timer's <tt>cancel</tt> 0N/A * method had been invoked. 0N/A * <p>This class is thread-safe: multiple threads can share a single 0N/A * <tt>Timer</tt> object without the need for external synchronization. 0N/A * <p>This class does <i>not</i> offer real-time guarantees: it schedules 0N/A * tasks using the <tt>Object.wait(long)</tt> method. 0N/A * <p>Java 5.0 introduced the {@code java.util.concurrent} package and 0N/A * one of the concurrency utilities therein is the {@link 0N/A * java.util.concurrent.ScheduledThreadPoolExecutor 0N/A * ScheduledThreadPoolExecutor} which is a thread pool for repeatedly 0N/A * executing tasks at a given rate or delay. It is effectively a more 0N/A * versatile replacement for the {@code Timer}/{@code TimerTask} 0N/A * combination, as it allows multiple service threads, accepts various 0N/A * time units, and doesn't require subclassing {@code TimerTask} (just 0N/A * implement {@code Runnable}). Configuring {@code 0N/A * ScheduledThreadPoolExecutor} with one thread makes it equivalent to 0N/A * <p>Implementation note: This class scales to large numbers of concurrently 0N/A * scheduled tasks (thousands should present no problem). Internally, 0N/A * it uses a binary heap to represent its task queue, so the cost to schedule 0N/A * a task is O(log n), where n is the number of concurrently scheduled tasks. 0N/A * <p>Implementation note: All constructors start a timer thread. 0N/A * @author Josh Bloch 0N/A * @see Object#wait(long) 0N/A * The timer task queue. This data structure is shared with the timer 0N/A * thread. The timer produces tasks, via its various schedule calls, 0N/A * and the timer thread consumes, executing timer tasks as appropriate, 0N/A * and removing them from the queue when they're obsolete. 0N/A * This object causes the timer's task execution thread to exit 0N/A * gracefully when there are no live references to the Timer object and no 0N/A * tasks in the timer queue. It is used in preference to a finalizer on 0N/A * Timer as such a finalizer would be susceptible to a subclass's 0N/A * finalizer forgetting to call it. 471N/A * This ID is used to generate thread names. 0N/A * Creates a new timer. The associated thread does <i>not</i> 0N/A * {@linkplain Thread#setDaemon run as a daemon}. 0N/A * Creates a new timer whose associated thread may be specified to 0N/A * {@linkplain Thread#setDaemon run as a daemon}. 0N/A * A daemon thread is called for if the timer will be used to 0N/A * schedule repeating "maintenance activities", which must be 0N/A * performed as long as the application is running, but should not 0N/A * prolong the lifetime of the application. 0N/A * @param isDaemon true if the associated thread should run as a daemon. 0N/A * Creates a new timer whose associated thread has the specified name. 0N/A * The associated thread does <i>not</i> 0N/A * {@linkplain Thread#setDaemon run as a daemon}. 0N/A * @param name the name of the associated thread 0N/A * @throws NullPointerException if {@code name} is null 0N/A * Creates a new timer whose associated thread has the specified name, 0N/A * and may be specified to 0N/A * {@linkplain Thread#setDaemon run as a daemon}. 0N/A * @param name the name of the associated thread 0N/A * @param isDaemon true if the associated thread should run as a daemon 0N/A * @throws NullPointerException if {@code name} is null 0N/A * Schedules the specified task for execution after the specified delay. 0N/A * @param task task to be scheduled. 0N/A * @param delay delay in milliseconds before task is to be executed. 0N/A * @throws IllegalArgumentException if <tt>delay</tt> is negative, or 0N/A * <tt>delay + System.currentTimeMillis()</tt> is negative. 0N/A * @throws IllegalStateException if task was already scheduled or 0N/A * cancelled, timer was cancelled, or timer thread terminated. 0N/A * @throws NullPointerException if {@code task} is null 0N/A * Schedules the specified task for execution at the specified time. If 0N/A * the time is in the past, the task is scheduled for immediate execution. 0N/A * @param task task to be scheduled. 0N/A * @param time time at which task is to be executed. 0N/A * @throws IllegalArgumentException if <tt>time.getTime()</tt> is negative. 0N/A * @throws IllegalStateException if task was already scheduled or 0N/A * cancelled, timer was cancelled, or timer thread terminated. 0N/A * @throws NullPointerException if {@code task} or {@code time} is null 0N/A * Schedules the specified task for repeated <i>fixed-delay execution</i>, 0N/A * beginning after the specified delay. Subsequent executions take place 0N/A * at approximately regular intervals separated by the specified period. 0N/A * <p>In fixed-delay execution, each execution is scheduled relative to 0N/A * the actual execution time of the previous execution. If an execution 0N/A * is delayed for any reason (such as garbage collection or other 0N/A * background activity), subsequent executions will be delayed as well. 0N/A * In the long run, the frequency of execution will generally be slightly 0N/A * lower than the reciprocal of the specified period (assuming the system 0N/A * clock underlying <tt>Object.wait(long)</tt> is accurate). 0N/A * <p>Fixed-delay execution is appropriate for recurring activities 0N/A * that require "smoothness." In other words, it is appropriate for 0N/A * activities where it is more important to keep the frequency accurate 0N/A * in the short run than in the long run. This includes most animation 0N/A * tasks, such as blinking a cursor at regular intervals. It also includes 0N/A * tasks wherein regular activity is performed in response to human 0N/A * input, such as automatically repeating a character as long as a key 0N/A * @param task task to be scheduled. 0N/A * @param delay delay in milliseconds before task is to be executed. 0N/A * @param period time in milliseconds between successive task executions. 0N/A * @throws IllegalArgumentException if {@code delay < 0}, or 0N/A * {@code delay + System.currentTimeMillis() < 0}, or 0N/A * {@code period <= 0} 0N/A * @throws IllegalStateException if task was already scheduled or 0N/A * cancelled, timer was cancelled, or timer thread terminated. 0N/A * @throws NullPointerException if {@code task} is null 0N/A * Schedules the specified task for repeated <i>fixed-delay execution</i>, 0N/A * beginning at the specified time. Subsequent executions take place at 0N/A * approximately regular intervals, separated by the specified period. 0N/A * <p>In fixed-delay execution, each execution is scheduled relative to 0N/A * the actual execution time of the previous execution. If an execution 0N/A * is delayed for any reason (such as garbage collection or other 0N/A * background activity), subsequent executions will be delayed as well. 0N/A * In the long run, the frequency of execution will generally be slightly 0N/A * lower than the reciprocal of the specified period (assuming the system 0N/A * clock underlying <tt>Object.wait(long)</tt> is accurate). As a 0N/A * consequence of the above, if the scheduled first time is in the past, 0N/A * it is scheduled for immediate execution. 0N/A * <p>Fixed-delay execution is appropriate for recurring activities 0N/A * that require "smoothness." In other words, it is appropriate for 0N/A * activities where it is more important to keep the frequency accurate 0N/A * in the short run than in the long run. This includes most animation 0N/A * tasks, such as blinking a cursor at regular intervals. It also includes 0N/A * tasks wherein regular activity is performed in response to human 0N/A * input, such as automatically repeating a character as long as a key 0N/A * @param task task to be scheduled. 0N/A * @param firstTime First time at which task is to be executed. 0N/A * @param period time in milliseconds between successive task executions. 0N/A * @throws IllegalArgumentException if {@code firstTime.getTime() < 0}, or 0N/A * {@code period <= 0} 0N/A * @throws IllegalStateException if task was already scheduled or 0N/A * cancelled, timer was cancelled, or timer thread terminated. 0N/A * @throws NullPointerException if {@code task} or {@code firstTime} is null 0N/A * Schedules the specified task for repeated <i>fixed-rate execution</i>, 0N/A * beginning after the specified delay. Subsequent executions take place 0N/A * at approximately regular intervals, separated by the specified period. 0N/A * <p>In fixed-rate execution, each execution is scheduled relative to the 0N/A * scheduled execution time of the initial execution. If an execution is 0N/A * delayed for any reason (such as garbage collection or other background 0N/A * activity), two or more executions will occur in rapid succession to 0N/A * "catch up." In the long run, the frequency of execution will be 0N/A * exactly the reciprocal of the specified period (assuming the system 0N/A * clock underlying <tt>Object.wait(long)</tt> is accurate). 0N/A * <p>Fixed-rate execution is appropriate for recurring activities that 0N/A * are sensitive to <i>absolute</i> time, such as ringing a chime every 0N/A * hour on the hour, or running scheduled maintenance every day at a 0N/A * particular time. It is also appropriate for recurring activities 0N/A * where the total time to perform a fixed number of executions is 0N/A * important, such as a countdown timer that ticks once every second for 0N/A * ten seconds. Finally, fixed-rate execution is appropriate for 0N/A * scheduling multiple repeating timer tasks that must remain synchronized 0N/A * with respect to one another. 0N/A * @param task task to be scheduled. 0N/A * @param delay delay in milliseconds before task is to be executed. 0N/A * @param period time in milliseconds between successive task executions. 0N/A * @throws IllegalArgumentException if {@code delay < 0}, or 0N/A * {@code delay + System.currentTimeMillis() < 0}, or 0N/A * {@code period <= 0} 0N/A * @throws IllegalStateException if task was already scheduled or 0N/A * cancelled, timer was cancelled, or timer thread terminated. 0N/A * @throws NullPointerException if {@code task} is null 0N/A * Schedules the specified task for repeated <i>fixed-rate execution</i>, 0N/A * beginning at the specified time. Subsequent executions take place at 0N/A * approximately regular intervals, separated by the specified period. 0N/A * <p>In fixed-rate execution, each execution is scheduled relative to the 0N/A * scheduled execution time of the initial execution. If an execution is 0N/A * delayed for any reason (such as garbage collection or other background 0N/A * activity), two or more executions will occur in rapid succession to 0N/A * "catch up." In the long run, the frequency of execution will be 0N/A * exactly the reciprocal of the specified period (assuming the system 0N/A * clock underlying <tt>Object.wait(long)</tt> is accurate). As a 0N/A * consequence of the above, if the scheduled first time is in the past, 0N/A * then any "missed" executions will be scheduled for immediate "catch up" 0N/A * <p>Fixed-rate execution is appropriate for recurring activities that 0N/A * are sensitive to <i>absolute</i> time, such as ringing a chime every 0N/A * hour on the hour, or running scheduled maintenance every day at a 0N/A * particular time. It is also appropriate for recurring activities 0N/A * where the total time to perform a fixed number of executions is 0N/A * important, such as a countdown timer that ticks once every second for 0N/A * ten seconds. Finally, fixed-rate execution is appropriate for 0N/A * scheduling multiple repeating timer tasks that must remain synchronized 0N/A * with respect to one another. 0N/A * @param task task to be scheduled. 0N/A * @param firstTime First time at which task is to be executed. 0N/A * @param period time in milliseconds between successive task executions. 0N/A * @throws IllegalArgumentException if {@code firstTime.getTime() < 0} or 0N/A * {@code period <= 0} 0N/A * @throws IllegalStateException if task was already scheduled or 0N/A * cancelled, timer was cancelled, or timer thread terminated. 0N/A * @throws NullPointerException if {@code task} or {@code firstTime} is null 0N/A * Schedule the specified timer task for execution at the specified 0N/A * time with the specified period, in milliseconds. If period is 0N/A * positive, the task is scheduled for repeated execution; if period is 0N/A * zero, the task is scheduled for one-time execution. Time is specified 0N/A * in Date.getTime() format. This method checks timer state, task state, 0N/A * and initial execution time, but not period. 0N/A * @throws IllegalArgumentException if <tt>time</tt> is negative. 0N/A * @throws IllegalStateException if task was already scheduled or 0N/A * cancelled, timer was cancelled, or timer thread terminated. 0N/A * @throws NullPointerException if {@code task} is null 479N/A // Constrain value of period sufficiently to prevent numeric 479N/A // overflow while still being effectively infinitely large. 0N/A "Task already scheduled or cancelled");
0N/A * Terminates this timer, discarding any currently scheduled tasks. 0N/A * Does not interfere with a currently executing task (if it exists). 0N/A * Once a timer has been terminated, its execution thread terminates 0N/A * gracefully, and no more tasks may be scheduled on it. 0N/A * <p>Note that calling this method from within the run method of a 0N/A * timer task that was invoked by this timer absolutely guarantees that 0N/A * the ongoing task execution is the last task execution that will ever 0N/A * be performed by this timer. 0N/A * <p>This method may be called repeatedly; the second and subsequent 0N/A * calls have no effect. 0N/A * Removes all cancelled tasks from this timer's task queue. <i>Calling 0N/A * this method has no effect on the behavior of the timer</i>, but 0N/A * eliminates the references to the cancelled tasks from the queue. 0N/A * If there are no external references to these tasks, they become 0N/A * eligible for garbage collection. 0N/A * <p>Most programs will have no need to call this method. 0N/A * It is designed for use by the rare application that cancels a large 0N/A * number of tasks. Calling this method trades time for space: the 0N/A * runtime of the method may be proportional to n + c log n, where n 0N/A * is the number of tasks in the queue and c is the number of cancelled 0N/A * <p>Note that it is permissible to call this method from within a 0N/A * a task scheduled on this timer. 0N/A * @return the number of tasks removed from the queue. 0N/A * This "helper class" implements the timer's task execution thread, which 0N/A * waits for tasks on the timer queue, executions them when they fire, 0N/A * reschedules repeating tasks, and removes cancelled tasks and spent 0N/A * non-repeating tasks from the queue. 0N/A * This flag is set to false by the reaper to inform us that there 0N/A * are no more live references to our Timer object. Once this flag 0N/A * is true and there are no more tasks in our queue, there is no 0N/A * work left for us to do, so we terminate gracefully. Note that 0N/A * this field is protected by queue's monitor! 0N/A * Our Timer's queue. We store this reference in preference to 0N/A * a reference to the Timer so the reference graph remains acyclic. 0N/A * Otherwise, the Timer would never be garbage-collected and this 0N/A * thread would never go away. 0N/A // Someone killed this Thread, behave as if Timer cancelled 0N/A * The main timer loop. (See class comment.) 0N/A // Wait for queue to become non-empty 0N/A break;
// Queue is empty and will forever remain; die 0N/A // Queue nonempty; look at first evt and do the right thing 0N/A continue;
// No action required, poll queue again 0N/A }
else {
// Repeating task, reschedule 0N/A * This class represents a timer task queue: a priority queue of TimerTasks, 0N/A * ordered on nextExecutionTime. Each Timer object has one of these, which it 0N/A * shares with its TimerThread. Internally this class uses a heap, which 0N/A * offers log(n) performance for the add, removeMin and rescheduleMin 0N/A * operations, and constant time performance for the getMin operation. 0N/A * Priority queue represented as a balanced binary heap: the two children 0N/A * of queue[n] are queue[2*n] and queue[2*n+1]. The priority queue is 0N/A * ordered on the nextExecutionTime field: The TimerTask with the lowest 0N/A * nextExecutionTime is in queue[1] (assuming the queue is nonempty). For 0N/A * each node n in the heap, and each descendant of n, d, 0N/A * n.nextExecutionTime <= d.nextExecutionTime. 0N/A * The number of tasks in the priority queue. (The tasks are stored in 0N/A * queue[1] up to queue[size]). 0N/A * Returns the number of tasks currently on the queue. 0N/A * Adds a new task to the priority queue. 0N/A // Grow backing store if necessary 0N/A * Return the "head task" of the priority queue. (The head task is an 0N/A * task with the lowest nextExecutionTime.) 0N/A * Return the ith task in the priority queue, where i ranges from 1 (the 0N/A * head task, which is returned by getMin) to the number of tasks on the 0N/A * Remove the head task from the priority queue. 0N/A * Removes the ith element from queue without regard for maintaining 0N/A * the heap invariant. Recall that queue is one-based, so 0N/A * Sets the nextExecutionTime associated with the head task to the 0N/A * specified value, and adjusts priority queue accordingly. 0N/A * Returns true if the priority queue contains no elements. 0N/A * Removes all elements from the priority queue. 0N/A // Null out task references to prevent memory leak 0N/A * Establishes the heap invariant (described above) assuming the heap 0N/A * satisfies the invariant except possibly for the leaf-node indexed by k 0N/A * (which may have a nextExecutionTime less than its parent's). 0N/A * This method functions by "promoting" queue[k] up the hierarchy 0N/A * (by swapping it with its parent) repeatedly until queue[k]'s 0N/A * nextExecutionTime is greater than or equal to that of its parent. 0N/A * Establishes the heap invariant (described above) in the subtree 0N/A * rooted at k, which is assumed to satisfy the heap invariant except 0N/A * possibly for node k itself (which may have a nextExecutionTime greater 0N/A * than its children's). 0N/A * This method functions by "demoting" queue[k] down the hierarchy 0N/A * (by swapping it with its smaller child) repeatedly until queue[k]'s 0N/A * nextExecutionTime is less than or equal to those of its children. 0N/A while ((j = k <<
1) <=
size && j >
0) {
0N/A j++;
// j indexes smallest kid 0N/A * Establishes the heap invariant (described above) in the entire tree, 0N/A * assuming nothing about the order of the elements prior to the call.