View Javadoc

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  	/* This may hang things up.
55  	  
56  	try {
57  	runner.join();
58  	
59  	Logger.getLogger(TaskQueue.class).debug("stop.after-join");
60  	} catch (InterruptedException x) {
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 }