1 package org.glassbox.executor;
2
3 import java.util.LinkedList;
4
5 import org.apache.log4j.Logger;
6
7 /***
8 This is a variation of Eric Crahen's ConcurrentExecutor.
9 The executor pattern was published by Eric Crahen.
10 Take a look at his <a href="http://www.cse.buffalo.edu/~crahen/papers/Executor.Pattern.pdf">paper</a>
11 to learn more about it.
12 */
13 public class TaskQueue implements Executor {
14 protected LinkedList queue = new LinkedList();
15 protected Handler handler;
16 protected Thread runner;
17
18 public TaskQueue() {
19 this(new NullHandler());
20 }
21
22 public TaskQueue(Handler handler) {
23 if(handler == null)
24 throw new NullPointerException();
25 this.handler = handler;
26 runner = new Thread(new ExecutorTask(), "glassbox.TaskQueue");
27 runner.start();
28 }
29
30 public void execute(Runnable task) {
31 synchronized(queue) {
32 queue.addLast(task);
33 queue.notify();
34 }
35 }
36
37 protected void setHandler(Handler handler) {
38 if(handler == null)
39 throw new NullPointerException();
40 this.handler = handler;
41 }
42
43 protected boolean isEmpty() {
44 return queue.isEmpty();
45 }
46
47 protected void stop() {
48 Logger.getLogger(TaskQueue.class).debug("stop()");
49
50 runner.interrupt();
51
52 Logger.getLogger(TaskQueue.class).debug("stop.after-interrupt");
53
54
55
56
57
58
59
60
61
62
63
64
65
66 Logger.getLogger(TaskQueue.class).debug("stop.exit");
67 }
68
69 private class ExecutorTask implements Runnable {
70 public void run() {
71 try {
72 while(!Thread.interrupted()) {
73 Runnable task = null;
74 synchronized(queue) {
75 while(queue.isEmpty()) queue.wait();
76 task = (Runnable)queue.removeFirst();
77 }
78
79 Logger.getLogger(TaskQueue.class).debug("run.before-task");
80
81 handler.beforeRun(task);
82
83 Logger.getLogger(TaskQueue.class).debug("run.running-task");
84
85 try {
86 task.run();
87 } catch(RuntimeException e) {
88 handler.afterFailure(task, e);
89 }
90
91 Logger.getLogger(TaskQueue.class).debug("run.task-finished");
92
93 handler.afterRun(task);
94
95 Logger.getLogger(TaskQueue.class).debug("run.end-of-while");
96 }
97 } catch(InterruptedException x) {
98 Logger.getLogger(TaskQueue.class).debug("run.interrupted-exception");
99 }
100 }
101 };
102 }