TimerTask.java revision 49965c1dc9da104344f4893a05e45795a5740d20
1/*
2 * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.util;
27
28/**
29 * A task that can be scheduled for one-time or repeated execution by a Timer.
30 *
31 * @author  Josh Bloch
32 * @see     Timer
33 * @since   1.3
34 */
35
36public abstract class TimerTask implements Runnable {
37    /**
38     * This object is used to control access to the TimerTask internals.
39     */
40    final Object lock = new Object();
41
42    /**
43     * The state of this task, chosen from the constants below.
44     */
45    int state = VIRGIN;
46
47    /**
48     * This task has not yet been scheduled.
49     */
50    static final int VIRGIN = 0;
51
52    /**
53     * This task is scheduled for execution.  If it is a non-repeating task,
54     * it has not yet been executed.
55     */
56    static final int SCHEDULED   = 1;
57
58    /**
59     * This non-repeating task has already executed (or is currently
60     * executing) and has not been cancelled.
61     */
62    static final int EXECUTED    = 2;
63
64    /**
65     * This task has been cancelled (with a call to TimerTask.cancel).
66     */
67    static final int CANCELLED   = 3;
68
69    /**
70     * Next execution time for this task in the format returned by
71     * System.currentTimeMillis, assuming this task is scheduled for execution.
72     * For repeating tasks, this field is updated prior to each task execution.
73     */
74    long nextExecutionTime;
75
76    /**
77     * Period in milliseconds for repeating tasks.  A positive value indicates
78     * fixed-rate execution.  A negative value indicates fixed-delay execution.
79     * A value of 0 indicates a non-repeating task.
80     */
81    long period = 0;
82
83    /**
84     * Creates a new timer task.
85     */
86    protected TimerTask() {
87    }
88
89    /**
90     * The action to be performed by this timer task.
91     */
92    public abstract void run();
93
94    /**
95     * Cancels this timer task.  If the task has been scheduled for one-time
96     * execution and has not yet run, or has not yet been scheduled, it will
97     * never run.  If the task has been scheduled for repeated execution, it
98     * will never run again.  (If the task is running when this call occurs,
99     * the task will run to completion, but will never run again.)
100     *
101     * <p>Note that calling this method from within the <tt>run</tt> method of
102     * a repeating timer task absolutely guarantees that the timer task will
103     * not run again.
104     *
105     * <p>This method may be called repeatedly; the second and subsequent
106     * calls have no effect.
107     *
108     * @return true if this task is scheduled for one-time execution and has
109     *         not yet run, or this task is scheduled for repeated execution.
110     *         Returns false if the task was scheduled for one-time execution
111     *         and has already run, or if the task was never scheduled, or if
112     *         the task was already cancelled.  (Loosely speaking, this method
113     *         returns <tt>true</tt> if it prevents one or more scheduled
114     *         executions from taking place.)
115     */
116    public boolean cancel() {
117        synchronized(lock) {
118            boolean result = (state == SCHEDULED);
119            state = CANCELLED;
120            return result;
121        }
122    }
123
124    /**
125     * Returns the <i>scheduled</i> execution time of the most recent
126     * <i>actual</i> execution of this task.  (If this method is invoked
127     * while task execution is in progress, the return value is the scheduled
128     * execution time of the ongoing task execution.)
129     *
130     * <p>This method is typically invoked from within a task's run method, to
131     * determine whether the current execution of the task is sufficiently
132     * timely to warrant performing the scheduled activity:
133     * <pre>
134     *   public void run() {
135     *       if (System.currentTimeMillis() - scheduledExecutionTime() >=
136     *           MAX_TARDINESS)
137     *               return;  // Too late; skip this execution.
138     *       // Perform the task
139     *   }
140     * </pre>
141     * This method is typically <i>not</i> used in conjunction with
142     * <i>fixed-delay execution</i> repeating tasks, as their scheduled
143     * execution times are allowed to drift over time, and so are not terribly
144     * significant.
145     *
146     * @return the time at which the most recent execution of this task was
147     *         scheduled to occur, in the format returned by Date.getTime().
148     *         The return value is undefined if the task has yet to commence
149     *         its first execution.
150     * @see Date#getTime()
151     */
152    public long scheduledExecutionTime() {
153        synchronized(lock) {
154            return (period < 0 ? nextExecutionTime + period
155                               : nextExecutionTime - period);
156        }
157    }
158}
159