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