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