KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > wings > util > TimerQueue


1 /*
2  * $Id: TimerQueue.java,v 1.3 2004/12/01 07:54:30 hengels Exp $
3  * Copyright 2000,2005 wingS development team.
4  *
5  * This file is part of wingS (http://www.j-wings.org).
6  *
7  * wingS is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1
10  * of the License, or (at your option) any later version.
11  *
12  * Please see COPYING for the complete licence.
13  */

14 package org.wings.util;
15
16 /*
17  * Die Klasse ist praktisch von der Swing Implementierung
18  * abgeleitet. Leider brauch ich einen Timer, der auch innerhalb des
19  * Swing Event Threads Impulse gibt. Deshalb angepasst. Ich hoffe das
20  * gibt keine Problemen mit dem Swing Team.
21  */

22
23 /**
24  * @author <a HREF="mailto:haaf@mercatis.de">Armin Haaf</a>
25  * @version $Revision: 1.3 $
26  */

27 public final class TimerQueue
28         implements Runnable JavaDoc {
29     /*
30      * Es gibt nur eine Queue pro Application.
31      */

32     private static TimerQueue sharedInstance = new TimerQueue();
33
34     private Timer firstTimer;
35     private boolean running;
36
37     /*
38      * Es gibt nur eine TimerQueue pro Application.
39      */

40     private TimerQueue() {
41         super();
42
43         // Now start the TimerQueue thread.
44
start();
45     }
46
47     /*
48      * Die eine Queue!!
49      */

50     public static TimerQueue sharedInstance() {
51         return sharedInstance;
52     }
53
54     private synchronized void start() {
55         System.err.println("Timer started");
56         if (running) {
57             throw new RuntimeException JavaDoc("Can't start a TimerQueue that is already running");
58         } else {
59             Thread JavaDoc timerThread = new Thread JavaDoc(this, "TimerQueue");
60
61             try {
62                 timerThread.setDaemon(true);
63             } catch (SecurityException JavaDoc e) {}
64             timerThread.start();
65             running = true;
66         }
67     }
68
69     private synchronized void stop() {
70         running = false;
71         notifyAll();
72     }
73
74     public synchronized void addTimer(Timer timer, long expirationTime) {
75         Timer previousTimer, nextTimer;
76
77         // If the Timer is already in the queue, then ignore the add.
78
if (timer.running) {
79             return;
80         }
81
82         previousTimer = null;
83         nextTimer = firstTimer;
84
85         // Insert the Timer into the linked list in the order they will
86
// expire. If two timers expire at the same time, put the newer entry
87
// later so they expire in the order they came in.
88

89         while (nextTimer != null) {
90             if (nextTimer.expirationTime > expirationTime)
91                 break;
92
93             previousTimer = nextTimer;
94             nextTimer = nextTimer.nextTimer;
95         }
96
97         if (previousTimer == null)
98             firstTimer = timer;
99         else
100             previousTimer.nextTimer = timer;
101
102         timer.expirationTime = expirationTime;
103         timer.nextTimer = nextTimer;
104         timer.running = true;
105         notifyAll();
106     }
107
108     public synchronized void removeTimer(Timer timer) {
109         boolean found;
110         Timer previousTimer, nextTimer;
111
112         if (!timer.running)
113             return;
114
115         previousTimer = null;
116         nextTimer = firstTimer;
117         found = false;
118
119         while (nextTimer != null) {
120             if (nextTimer == timer) {
121                 found = true;
122                 break;
123             }
124
125             previousTimer = nextTimer;
126             nextTimer = nextTimer.nextTimer;
127         }
128
129         if (!found)
130             return;
131
132         if (previousTimer == null)
133             firstTimer = timer.nextTimer;
134         else
135             previousTimer.nextTimer = timer.nextTimer;
136
137         timer.expirationTime = 0;
138         timer.nextTimer = null;
139         timer.running = false;
140     }
141
142     public synchronized boolean containsTimer(Timer timer) {
143         return timer.running;
144     }
145
146     // If there are a ton of timers, this method may never return. It loops
147
// checking to see if the head of the Timer list has expired. If it has,
148
// it posts the Timer and reschedules it if necessary.
149

150     public synchronized long postExpiredTimers() {
151         long currentTime, timeToWait;
152         Timer timer;
153
154         // The timeToWait we return should never be negative and only be zero
155
// when we have no Timers to wait for.
156

157         do {
158             timer = firstTimer;
159             if (timer == null)
160                 return 0;
161
162             currentTime = System.currentTimeMillis();
163             timeToWait = timer.expirationTime - currentTime;
164
165             if (timeToWait <= 0) {
166                 try {
167                     timer.post(); // have timer post an event
168
} catch (SecurityException JavaDoc e) {}
169
170                 // remove the timer from the queue
171
removeTimer(timer);
172
173                 // This tries to keep the interval uniform at the cost of
174
// drift.
175
if (timer.isRepeats()) {
176                     addTimer(timer, currentTime + timer.getDelay());
177                 }
178             }
179
180             // Allow other threads to call addTimer() and removeTimer()
181
// even when we are posting Timers like mad. Since the wait()
182
// releases the lock, be sure not to maintain any state
183
// between iterations of the loop.
184

185             try {
186                 wait(1);
187             } catch (InterruptedException JavaDoc e) {
188             }
189         } while (timeToWait <= 0);
190
191         return timeToWait;
192     }
193
194     public synchronized void run() {
195         long timeToWait;
196
197         try {
198             while (running) {
199                 timeToWait = postExpiredTimers();
200                 try {
201                     wait(timeToWait);
202                 } catch (InterruptedException JavaDoc e) { }
203             }
204         } catch (ThreadDeath JavaDoc td) {
205             running = false;
206             // Mark all the timers we contain as not being queued.
207
Timer timer = firstTimer;
208             while (timer != null) {
209                 timer.eventQueued = false;
210                 timer = timer.nextTimer;
211             }
212             sharedInstance.start();
213             throw td;
214         }
215     }
216
217     public synchronized String JavaDoc toString() {
218         StringBuffer JavaDoc buf;
219         Timer nextTimer;
220
221         buf = new StringBuffer JavaDoc();
222         buf.append("TimerQueue (");
223
224         nextTimer = firstTimer;
225         while (nextTimer != null) {
226             buf.append(nextTimer.toString());
227
228             nextTimer = nextTimer.nextTimer;
229             if (nextTimer != null)
230                 buf.append(", ");
231         }
232
233         buf.append(")");
234         return buf.toString();
235     }
236 }
237
238
239
Popular Tags