View Javadoc

1   package org.xvsm.internal;
2   
3   import java.util.concurrent.ExecutorService;
4   import java.util.concurrent.Executors;
5   import java.util.concurrent.TimeUnit;
6   
7   import org.apache.log4j.Logger;
8   import org.xvsm.configuration.ConfigurationManager;
9   import org.xvsm.internal.exceptions.FatalException;
10  import org.xvsm.internal.tasks.Task;
11  
12  /***
13   * 
14   * @author Christian Schreiber, Michael Proestler
15   * 
16   */
17  public final class EventProcessingPool {
18  
19  	/***
20  	 * True if the Pool is still running. False otherwise.
21  	 */
22  	private static boolean running = false;
23  
24  	/***
25  	 * The logger.
26  	 */
27  	private static Logger logger = Logger.getLogger(EventProcessingPool.class);
28  
29  	/***
30  	 * The maximal amount of Threads in the EventProcessingPool.
31  	 */
32  	private int maxThreads;
33  
34  	private static EventProcessingPool pool;
35  
36  	/***
37  	 * The ExectorService of the EventProcessingPool.
38  	 */
39  	private ExecutorService service;
40  
41  	public static synchronized EventProcessingPool getInstance() {
42  		if (pool == null) {
43  			pool = new EventProcessingPool();
44  		}
45  		return pool;
46  	}
47  
48  	/***
49  	 * Default constructor. Private because utility classes must not have a
50  	 * public default constructor.
51  	 */
52  	private EventProcessingPool() {
53  		this.init();
54  	}
55  
56  	/***
57  	 * Tries to dispatch the given runnable to a thread. If all threads are
58  	 * working, the runnable will be put in the internal queue.
59  	 * 
60  	 * @param task
61  	 *            The task to be run by an thread.
62  	 */
63  	public void execute(Task task) {
64  		if (logger.isDebugEnabled()) {
65  			logger.debug("execute(" + task + ")");
66  		}
67  		service.execute(task);
68  	}
69  
70  	/***
71  	 * Initiates an orderly shutdown in which previously submitted tasks are
72  	 * executed, but no new tasks will be accepted.
73  	 * 
74  	 */
75  	public void shutdown() {
76  		if (running) {
77  			service.shutdown(); // Disable new tasks from being submitted
78  			try {
79  				// Wait a while for existing tasks to terminate
80  				if (!service.awaitTermination(60, TimeUnit.SECONDS)) {
81  					service.shutdownNow(); // Cancel currently executing tasks
82  					running = false;
83  					// Wait a while for tasks to respond to being cancelled
84  					if (!service.awaitTermination(60, TimeUnit.SECONDS))
85  						throw new FatalException("Pool did not terminate");
86  				}
87  				running = false;
88  			} catch (InterruptedException ie) {
89  				// (Re-)Cancel if current thread also interrupted
90  				service.shutdownNow();
91  				running = false;
92  				// Preserve interrupt status
93  				Thread.currentThread().interrupt();
94  			}
95  		}
96  		EventProcessingPool.pool = null;
97  
98  	}
99  
100 	/***
101 	 * Persudes the EventProcessingPool to re-read the configuration file and
102 	 * restart the pool with the new configuration.
103 	 * 
104 	 */
105 	private void init() {
106 		maxThreads = ConfigurationManager.getInstance().getIntegerSetting(
107 				"EventProcessingThreads");
108 		service = Executors.newCachedThreadPool();// newFixedThreadPool(maxThreads);
109 		running = true;
110 	}
111 }