KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mx > util > SchedulableRunnable


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.mx.util;
23
24 import EDU.oswego.cs.dl.util.concurrent.SynchronizedLong;
25 import org.jboss.util.timeout.Timeout;
26
27 /**
28  * A schedulable runnable.<p>
29  *
30  * Subclasses should implement doRun() to do some real work.<p>
31  *
32  * setScheduler(RunnableScheduler) has to be invoked with a RunnableScheduler
33  * that has been started for the work to be performed. If the doRun() does
34  * not invoke setNextRun(), the link to the scheduler is removed.
35  *
36  * @see RunnableScheduler
37  *
38  * @author <a HREF="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
39  * @author Scott.Stark@jboss.org
40  * @version $Revision: 58167 $
41  */

42 public abstract class SchedulableRunnable
43    implements Runnable JavaDoc
44 {
45    // Attributes ----------------------------------------------------
46

47    /**
48     * The next run timestamp
49     */

50    private SynchronizedLong nextRun = new SynchronizedLong(0);
51
52    /**
53     * The current scheduler
54     */

55    private RunnableScheduler scheduler;
56
57    /**
58     * Whether we are running
59     */

60    private boolean running;
61
62    /**
63     * Whether we should reschedule after the run
64     */

65    private boolean reschedule;
66
67    /**
68     * Handle for canceling ourselves.
69     */

70    private Timeout timeout;
71
72    // Static --------------------------------------------------------
73

74    // Constructors --------------------------------------------------
75

76    /**
77     * Constructs a new schedulable runnable.
78     */

79    public SchedulableRunnable()
80    {
81    }
82
83    // Public --------------------------------------------------------
84

85    /**
86     * Gets the next run timestamp
87     *
88     * @return the next run
89     */

90    public long getNextRun()
91    {
92       return nextRun.get();
93    }
94
95    /**
96     * Sets the next run date<p>
97     *
98     * If it is linked to a scheduler, it is temporarily removed while the date
99     * is modified.
100     *
101     * @param nextRun the next run date
102     */

103    public synchronized void setNextRun(long nextRun)
104    {
105       // Remove from scheduler
106
if (timeout != null)
107          timeout.cancel();
108
109       // Set the new run time
110
this.nextRun.set(nextRun);
111
112       // If we are not running, add it to the scheduler otherwise
113
// remember we want adding back
114
if (running == false && scheduler != null)
115       {
116          //log.debug("add to scheduler: " + this);
117
timeout = scheduler.add(this);
118       }
119       else
120       {
121          //log.debug("reschedule: " + this);
122
reschedule = true;
123       }
124    }
125
126    /**
127     * Set the scheduler for this runnable
128     *
129     * @param scheduler pass null to remove the runnable from any scheduler
130     * @return the previous scheduler or null if there was no previous scheduler
131     */

132    public synchronized RunnableScheduler setScheduler(RunnableScheduler scheduler)
133    {
134       // Null operation
135
if (this.scheduler == scheduler)
136          return this.scheduler;
137
138       // Remember the result
139
RunnableScheduler result = this.scheduler;
140
141       // Remove from previous scheduler
142
if (this.timeout != null)
143          timeout.cancel();
144
145       // Set the new state
146
this.scheduler = scheduler;
147
148       // This is a remove operation
149
if (scheduler == null)
150          reschedule = false;
151
152       // If we are not running, add it to the scheduler otherwise
153
// remember we want adding
154
else if (running == false)
155          timeout = scheduler.add(this);
156       else
157          reschedule = true;
158
159       // We are done
160
return result;
161    }
162
163    /**
164     * Do the work, the scheduled runnable should do its work here
165     */

166    public abstract void doRun();
167
168    // Runnable Implementation ---------------------------------------
169

170    /**
171     * Runs doRun()<p>
172     *
173     * If setNextRun() is not invoked during the doRun(), the link to the
174     * scheduler is removed
175     */

176    public final void run()
177    {
178       startRun();
179       try
180       {
181          doRun();
182       }
183       finally
184       {
185          endRun();
186       }
187    }
188
189    // Object Overrides ----------------------------------------------
190

191    // Protected -----------------------------------------------------
192

193    // Package -------------------------------------------------------
194

195    // Private -------------------------------------------------------
196

197    /**
198     * Start the run
199     */

200    private synchronized void startRun()
201    {
202       running = true;
203    }
204
205    /**
206     * Check whether the work got rescheduled
207     */

208    private synchronized void endRun()
209    {
210       running = false;
211       if (reschedule == true)
212          timeout = scheduler.add(this);
213       reschedule = false;
214    }
215
216    // Inner Classes -------------------------------------------------
217
}
218
219
Popular Tags