KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > dyade > aaa > util > Timer


1 /*
2  * Copyright (C) 2002 - 2004 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 fr.dyade.aaa.util;
22
23 import java.util.Vector JavaDoc;
24
25 import org.objectweb.util.monolog.api.BasicLevel;
26
27 /**
28  * This class is a facility for scheduling tasks future execution.
29  *
30  * <p>It is a simplified version of the timer provided by the jdk1.3.
31  */

32 public class Timer {
33   /** <code>true</code> if the timer has been cancelled. */
34   private boolean cancelled = false;
35   /** The timer's daemon. */
36   TimerDaemon daemon;
37   /** The timer's tasks. */
38   Vector JavaDoc tasks;
39
40   /** Constructs a <code>Timer</code> instance. */
41   public Timer() {
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     if (cancelled)
58       throw new IllegalStateException JavaDoc("Timer has been cancelled.");
59     if (tasks.contains(task))
60       throw new IllegalStateException JavaDoc("Task is already scheduled.");
61     if (task.cancelled)
62       throw new IllegalStateException JavaDoc("Task has been cancelled.");
63
64     if (delay < 0)
65       throw new IllegalArgumentException JavaDoc("Invalid negative delay: " + delay);
66
67     long wakeupTime = System.currentTimeMillis() + delay;
68     insertTask(task, wakeupTime);
69     if (!daemon.started)
70       daemon.start();
71     this.notify();
72
73   }
74
75   /** Cancels the timer and all its non executed tasks. */
76   public synchronized void cancel() {
77     cancelled = true;
78
79     if (!daemon.started) return;
80     tasks.removeAllElements();
81     daemon.running = false;
82     daemon.shutdown();
83   }
84
85   /** Inserts a task in the timer's tasks list. */
86   private void insertTask(TimerTask task, long wakeupTime) {
87     task.timer = this;
88     task.wakeupTime = wakeupTime;
89
90     int i = 0;
91     TimerTask currentTask;
92     while (i < tasks.size()) {
93       currentTask = (TimerTask) tasks.elementAt(i);
94
95       if (currentTask.wakeupTime > wakeupTime) {
96         tasks.insertElementAt(task, i);
97         break;
98       } else
99         i++;
100     }
101     if (i == tasks.size())
102       tasks.addElement(task);
103
104   }
105 }
106
107 /** The timer's daemon, actually scheduling the tasks. */
108 class TimerDaemon extends Daemon {
109   /** The timer the daemon belongs to. */
110   private Timer timer;
111   /** The next wake up time of the daemon. */
112   long nextWakeup = -1;
113   /** <code>true</code> if the daemon is actually started. */
114   boolean started = false;
115
116   /** Constructs a <code>TimerDaemon</code> instance for a given timer. */
117   TimerDaemon(Timer timer) {
118     super("timer");
119     setDaemon(true);
120     this.timer = timer;
121   }
122
123   /** Starts the daemon. */
124   public void start() {
125     super.start();
126     started = true;
127   }
128
129   /** Daemon's loop. */
130   public void run() {
131     try {
132       TimerTask task = null;
133       while (running) {
134         canStop = true;
135
136         task = null;
137         try {
138           synchronized (timer) {
139             if (timer.tasks.isEmpty()) {
140               logmon.log(BasicLevel.DEBUG,
141                          getName() + ", run and wait()");
142               timer.wait();
143             } else {
144               task = (TimerTask) timer.tasks.elementAt(0);
145               nextWakeup = task.wakeupTime;
146               long sleepPeriod = nextWakeup - System.currentTimeMillis();
147               if (sleepPeriod <= 0) {
148                 // trigger the task immediately
149

150                 logmon.log(BasicLevel.DEBUG,
151                            getName() + ", run, remove task and continue");
152                 timer.tasks.removeElementAt(0);
153                 canStop = false;
154               } else {
155                 // wait for some time till the next planned waking up.
156
logmon.log(BasicLevel.DEBUG,
157                            getName() + ", run and wait("+sleepPeriod+")");
158                 task.waiting = true;
159                 timer.wait(sleepPeriod);
160                 task = null;
161               }
162             }
163
164           }
165           if (task != null) {
166             canStop = false;
167             // execute the task outside of mutual exclusion section
168
task.run();
169             task = null;
170           }
171         } catch (InterruptedException JavaDoc e1) {
172           // nothing to be done, continue normal loop
173
logmon.log(BasicLevel.DEBUG,
174                      getName() + ", run," + e1.toString());
175         }
176
177       }
178       started = false;
179     } catch (Exception JavaDoc e) {
180       logmon.log(BasicLevel.WARN,
181                  getName() + ", run," + e.toString());
182     } finally {
183       finish();
184     }
185   }
186
187   /** Interrupts the thread. */
188   public synchronized void interrupt() {
189     if (canStop)
190       thread.interrupt();
191   }
192
193   /** Shuts the daemon down. */
194   public void shutdown() {
195     timer.notify();
196   }
197
198   /** Releases the daemon's resources. */
199   public void close() {
200   }
201 }
202
Popular Tags