1 /*
2 * Copyright (c) 1999, 2013, 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
26 package java.util;
27
28 /**
29 * A task that can be scheduled for one-time or repeated execution by a
30 * {@link Timer}.
31 *
32 * <p>A timer task is <em>not</em> reusable. Once a task has been scheduled
33 * for execution on a {@code Timer} or cancelled, subsequent attempts to
34 * schedule it for execution will throw {@code IllegalStateException}.
35 *
36 * @author Josh Bloch
37 * @since 1.3
38 */
39
40 public abstract class TimerTask implements Runnable {
41 /**
42 * This object is used to control access to the TimerTask internals.
43 */
44 final Object lock = new Object();
45
46 /**
47 * The state of this task, chosen from the constants below.
48 */
49 int state = VIRGIN;
50
51 /**
52 * This task has not yet been scheduled.
53 */
54 static final int VIRGIN = 0;
55
56 /**
57 * This task is scheduled for execution. If it is a non-repeating task,
58 * it has not yet been executed.
59 */
60 static final int SCHEDULED = 1;
61
62 /**
63 * This non-repeating task has already executed (or is currently
64 * executing) and has not been cancelled.
65 */
66 static final int EXECUTED = 2;
67
68 /**
69 * This task has been cancelled (with a call to TimerTask.cancel).
70 */
71 static final int CANCELLED = 3;
72
73 /**
74 * Next execution time for this task in the format returned by
75 * System.currentTimeMillis, assuming this task is scheduled for execution.
76 * For repeating tasks, this field is updated prior to each task execution.
77 */
78 long nextExecutionTime;
79
80 /**
81 * Period in milliseconds for repeating tasks. A positive value indicates
82 * fixed-rate execution. A negative value indicates fixed-delay execution.
83 * A value of 0 indicates a non-repeating task.
84 */
85 long period = 0;
86
87 /**
88 * Creates a new timer task.
89 */
90 protected TimerTask() {
91 }
92
93 /**
94 * The action to be performed by this timer task.
95 */
96 public abstract void run();
97
98 /**
99 * Cancels this timer task. If the task has been scheduled for one-time
100 * execution and has not yet run, or has not yet been scheduled, it will
101 * never run. If the task has been scheduled for repeated execution, it
102 * will never run again. (If the task is running when this call occurs,
103 * the task will run to completion, but will never run again.)
104 *
105 * <p>Note that calling this method from within the {@code run} method of
106 * a repeating timer task absolutely guarantees that the timer task will
107 * not run again.
108 *
109 * <p>This method may be called repeatedly; the second and subsequent
110 * calls have no effect.
111 *
112 * @return true if this task is scheduled for one-time execution and has
113 * not yet run, or this task is scheduled for repeated execution.
114 * Returns false if the task was scheduled for one-time execution
115 * and has already run, or if the task was never scheduled, or if
116 * the task was already cancelled. (Loosely speaking, this method
117 * returns {@code true} if it prevents one or more scheduled
118 * executions from taking place.)
119 */
120 public boolean cancel() {
121 synchronized(lock) {
122 boolean result = (state == SCHEDULED);
123 state = CANCELLED;
124 return result;
125 }
126 }
127
128 /**
129 * Returns the <i>scheduled</i> execution time of the most recent
130 * <i>actual</i> execution of this task. (If this method is invoked
131 * while task execution is in progress, the return value is the scheduled
132 * execution time of the ongoing task execution.)
133 *
134 * <p>This method is typically invoked from within a task's run method, to
135 * determine whether the current execution of the task is sufficiently
136 * timely to warrant performing the scheduled activity:
137 * <pre>{@code
138 * public void run() {
139 * if (System.currentTimeMillis() - scheduledExecutionTime() >=
140 * MAX_TARDINESS)
141 * return; // Too late; skip this execution.
142 * // Perform the task
143 * }
144 * }</pre>
145 * This method is typically <i>not</i> used in conjunction with
146 * <i>fixed-delay execution</i> repeating tasks, as their scheduled
147 * execution times are allowed to drift over time, and so are not terribly
148 * significant.
149 *
150 * @return the time at which the most recent execution of this task was
151 * scheduled to occur, in the format returned by Date.getTime().
152 * The return value is undefined if the task has yet to commence
153 * its first execution.
154 * @see Date#getTime()
155 */
156 public long scheduledExecutionTime() {
157 synchronized(lock) {
158 return (period < 0 ? nextExecutionTime + period
159 : nextExecutionTime - period);
160 }
161 }
162 }
163