KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > scalagent > kjoram > util > Timer


1 /*
2  * Copyright (C) 2002 - ScalAgent Distributed Technologies
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA.
18  *
19  * The present code contributor is ScalAgent Distributed Technologies.
20  */

21 package com.scalagent.kjoram.util;
22
23 import java.util.Vector JavaDoc;
24
25 /**
26  * This class is a facility for scheduling tasks future execution.
27  *
28  * <p>It is a simplified version of the timer provided by the jdk1.3.
29  */

30 public class Timer
31 {
32   /** <code>true</code> if the timer has been cancelled. */
33   private boolean cancelled = false;
34   /** The timer's daemon. */
35   TimerDaemon daemon;
36   /** The timer's tasks. */
37   Vector JavaDoc tasks;
38
39   /** Constructs a <code>Timer</code> instance. */
40   public Timer()
41   {
42     tasks = new Vector JavaDoc();
43     daemon = new TimerDaemon(this);
44   }
45
46   /**
47    * Schedules a given task for execution after a given delay.
48    *
49    * @param task The task to be executed.
50    * @param delay Delay in ms before executing the task.
51    * @exception IllegalStateException If the timer or the task have already
52    * been cancelled, or if the task is already scheduled.
53    * @exception IllegalArgumentException If the delay is negative.
54    */

55   public synchronized void schedule(TimerTask task, long delay)
56                          throws Exception JavaDoc
57   {
58     if (cancelled)
59       throw new IllegalStateException JavaDoc("Timer has been cancelled.");
60     if (tasks.contains(task))
61       throw new IllegalStateException JavaDoc("Task is already scheduled.");
62     if (task.cancelled)
63       throw new IllegalStateException JavaDoc("Task has been cancelled.");
64
65     if (delay < 0)
66       throw new IllegalArgumentException JavaDoc("Invalid negative delay: " + delay);
67    
68     long wakeupTime = System.currentTimeMillis() + delay;
69     insertTask(task, wakeupTime);
70
71     if (wakeupTime < daemon.nextWakeup)
72       daemon.interrupt();
73    
74     if (! daemon.started)
75       daemon.start();
76   }
77
78   /** Cancels the timer and all its non executed tasks. */
79   public synchronized void cancel()
80   {
81     cancelled = true;
82
83     if (! daemon.started)
84       return;
85
86     tasks.removeAllElements();
87
88     daemon.interrupt();
89   }
90
91   /** Inserts a task in the timer's tasks list. */
92   private void insertTask(TimerTask task, long wakeupTime)
93   {
94     task.timer = this;
95     task.wakeupTime = wakeupTime;
96
97     int i = 0;
98     TimerTask currentTask;
99     while (i < tasks.size()) {
100       currentTask = (TimerTask) tasks.elementAt(i);
101
102       if (currentTask.wakeupTime > wakeupTime) {
103         tasks.insertElementAt(task, i);
104         break;
105       }
106       else
107         i++;
108     }
109     if (i == tasks.size())
110       tasks.addElement(task);
111   }
112 }
113
114
115 /** The timer's daemon, actually scheduling the tasks. */
116 class TimerDaemon extends Daemon
117 {
118   /** The timer the daemon belongs to. */
119   private Timer timer;
120   /** <code>true</code> if the daemon is currently waiting. */
121   private boolean waiting = false;
122   /** The next wake up time of the daemon. */
123   long nextWakeup = -1;
124   /** <code>true</code> if the daemon is actually started. */
125   boolean started = false;
126
127
128   /** Constructs a <code>TimerDaemon</code> instance for a given timer. */
129   TimerDaemon(Timer timer)
130   {
131     super("timer");
132     setDaemon(true);
133     this.timer = timer;
134   }
135
136   /** Starts the daemon. */
137   public void start()
138   {
139     super.start();
140     started = true;
141   }
142
143   /** Daemon's loop. */
144   public void run()
145   {
146     try {
147       TimerTask task = null;
148       while (running) {
149         canStop = true;
150   
151         synchronized (timer) {
152           if (timer.tasks.isEmpty()) {
153             started = false;
154             break;
155           }
156
157           task = (TimerTask) timer.tasks.elementAt(0);
158           nextWakeup = task.wakeupTime;
159         }
160
161         try {
162           synchronized (this) {
163             waiting = true;
164             task.waiting = true;
165             try {
166               this.wait(nextWakeup - System.currentTimeMillis());
167             }
168             catch (IllegalArgumentException JavaDoc illAE) {}
169           }
170  
171           synchronized (timer) {
172             canStop = false;
173             waiting = false;
174             nextWakeup = -1;
175             task.run();
176             timer.tasks.removeElement(task);
177           }
178         }
179         catch (InterruptedException JavaDoc iE0) {}
180       }
181     }
182     catch (Exception JavaDoc e) {}
183     finally {
184       finish();
185     }
186   }
187
188   /** Interrupts the thread. */
189   public synchronized void interrupt()
190   {
191     if (waiting)
192       //thread.interrupt();
193
stop();
194   }
195
196   /** Shuts the daemon down. */
197   public void shutdown()
198   {}
199
200   /** Releases the daemon's resources. */
201   public void close()
202   {}
203 }
204
Popular Tags