1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.scheduler;
19
20 import java.util.List;
21 import java.util.Vector;
22
23
24
25
26
27
28
29
30
31
32
33 public class Scheduler extends Thread {
34
35
36
37
38 List jobList;
39
40
41
42 boolean shutdown = false;
43
44
45
46
47 public Scheduler() {
48 super();
49 jobList = new Vector();
50 }
51
52
53
54
55
56
57 int findIndex(final Job job) {
58 int size = jobList.size();
59 boolean found = false;
60
61 int i = 0;
62 for (; i < size; i++) {
63 ScheduledJobEntry se = (ScheduledJobEntry) jobList.get(i);
64 if (se.job == job) {
65 found = true;
66 break;
67 }
68 }
69 if (found) {
70 return i;
71 } else {
72 return -1;
73 }
74 }
75
76
77
78
79
80
81
82
83 public synchronized boolean delete(final Job job) {
84
85
86 if (shutdown) {
87 return false;
88 }
89 int i = findIndex(job);
90 if (i != -1) {
91 ScheduledJobEntry se = (ScheduledJobEntry) jobList.remove(i);
92 if (se.job != job) {
93 new IllegalStateException("Internal programming error");
94 }
95
96
97 if (i == 0) {
98 this.notifyAll();
99 }
100 return true;
101 } else {
102 return false;
103 }
104 }
105
106
107
108
109
110
111
112
113 public synchronized void schedule(final Job job,
114 final long desiredTime) {
115 schedule(new ScheduledJobEntry(job, desiredTime));
116 }
117
118
119
120
121
122
123
124
125
126
127
128 public synchronized void schedule(final Job job,
129 final long desiredTime,
130 final long period) {
131 schedule(new ScheduledJobEntry(job, desiredTime, period));
132 }
133
134
135
136
137
138
139
140
141
142
143
144 public synchronized boolean changePeriod(final Job job,
145 final long newPeriod) {
146 if (newPeriod <= 0) {
147 throw new IllegalArgumentException(
148 "Period must be an integer langer than zero");
149 }
150
151 int i = findIndex(job);
152 if (i == -1) {
153 return false;
154 } else {
155 ScheduledJobEntry se = (ScheduledJobEntry) jobList.get(i);
156 se.period = newPeriod;
157 return true;
158 }
159 }
160
161
162
163
164
165 private synchronized void schedule(final ScheduledJobEntry newSJE) {
166
167 if (shutdown) {
168 return;
169 }
170 int max = jobList.size();
171 long desiredExecutionTime = newSJE.desiredExecutionTime;
172
173
174 int i = 0;
175 for (; i < max; i++) {
176
177 ScheduledJobEntry sje = (ScheduledJobEntry) jobList.get(i);
178
179 if (desiredExecutionTime < sje.desiredExecutionTime) {
180 break;
181 }
182 }
183 jobList.add(i, newSJE);
184
185 if (i == 0) {
186 this.notifyAll();
187 }
188 }
189
190
191
192
193 public synchronized void shutdown() {
194 shutdown = true;
195 }
196
197
198
199
200 public synchronized void run() {
201 while (!shutdown) {
202 if (jobList.isEmpty()) {
203 linger();
204 } else {
205 ScheduledJobEntry sje = (ScheduledJobEntry) jobList.get(0);
206 long now = System.currentTimeMillis();
207 if (now >= sje.desiredExecutionTime) {
208 executeInABox(sje.job);
209 jobList.remove(0);
210 if (sje.period > 0) {
211 sje.desiredExecutionTime = now + sje.period;
212 schedule(sje);
213 }
214 } else {
215 linger(sje.desiredExecutionTime - now);
216 }
217 }
218 }
219
220 jobList.clear();
221 jobList = null;
222 System.out.println("Leaving scheduler run method");
223 }
224
225
226
227
228
229 void executeInABox(final Job job) {
230 try {
231 job.execute();
232 } catch (Exception e) {
233 System.err.println("The execution of the job threw an exception");
234 e.printStackTrace(System.err);
235 }
236 }
237
238
239
240
241 void linger() {
242 try {
243 while (jobList.isEmpty() && !shutdown) {
244 this.wait();
245 }
246 } catch (InterruptedException ie) {
247 shutdown = true;
248 }
249 }
250
251
252
253
254
255 void linger(final long timeToLinger) {
256 try {
257 this.wait(timeToLinger);
258 } catch (InterruptedException ie) {
259 shutdown = true;
260 }
261 }
262
263
264
265
266 static final class ScheduledJobEntry {
267
268
269
270 long desiredExecutionTime;
271
272
273
274 Job job;
275
276
277
278 long period = 0;
279
280
281
282
283
284
285 ScheduledJobEntry(final Job job, final long desiredTime) {
286 this(job, desiredTime, 0);
287 }
288
289
290
291
292
293
294
295 ScheduledJobEntry(final Job job,
296 final long desiredTime,
297 final long period) {
298 super();
299 this.desiredExecutionTime = desiredTime;
300 this.job = job;
301 this.period = period;
302 }
303 }
304
305 }
306
307