KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > oddjob > util > ThreadManager


1 /*
2  * (c) Rob Gordon 2005
3  */

4 package org.oddjob.util;
5
6 import java.util.ArrayList JavaDoc;
7 import java.util.HashMap JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.List JavaDoc;
10 import java.util.Map JavaDoc;
11
12 import org.apache.log4j.Logger;
13 import org.oddjob.Stoppable;
14
15 /**
16  * The thread manager keeps track of active threads. It can be used to
17  * ensure that all threads are complete before a job terminates.
18  */

19 public class ThreadManager {
20     private static final Logger logger = Logger.getLogger(ThreadManager.class);
21     
22     /** The context ClassLoader for running the job */
23     private volatile ClassLoader JavaDoc classLoader;
24     
25     /** Map of active threads to their description. */
26     private final Map JavaDoc /*<Thread, Remember>*/ activeThreads = new HashMap JavaDoc();
27
28     /**
29      * Constructor.
30      *
31      */

32     public ThreadManager() {
33         classLoader = Thread.currentThread().getContextClassLoader();
34     }
35     
36     /**
37      * Run a job with the given classloader.
38      *
39      * @param runnable The job.
40      * @param description The description of the job.
41      * @param classLoader The ClassLoader.
42      */

43     public void run(final Runnable JavaDoc runnable, final String JavaDoc description,
44             final ClassLoader JavaDoc classLoader) {
45         Runnable JavaDoc wrapper = new Runnable JavaDoc() {
46             public void run() {
47                 ClassLoader JavaDoc existing = Thread.currentThread().getContextClassLoader();
48                 try {
49                     if (classLoader != null) {
50                         Thread.currentThread().setContextClassLoader(classLoader);
51                     }
52                     runnable.run();
53                 }
54                 catch (Throwable JavaDoc t) {
55                     logger.error("Failed running [" + description + "]", t);
56                 }
57                 finally {
58                     synchronized (activeThreads) {
59                         activeThreads.remove(Thread.currentThread());
60                     }
61                     // don't really need this as the thread is about to die
62
// but I like to be neat.
63
Thread.currentThread().setContextClassLoader(existing);
64                 }
65             }
66         };
67         Thread JavaDoc t = new Thread JavaDoc(wrapper);
68         synchronized (activeThreads) {
69             activeThreads.put(t, new Remember(description, runnable));
70         }
71         t.start();
72     }
73     
74     /**
75      * Run a job with the default ClassLoader
76      *
77      * @param runnable The job.
78      * @param description The description.
79      */

80     public void run(Runnable JavaDoc runnable, String JavaDoc description) {
81         run(runnable, description, classLoader);
82     }
83     
84     /**
85      * Return a array of the descriptions of all active threads.
86      * The description of the thread making the request is excluded. This
87      * is because method is used to see if a server can stop, so a server
88      * can run a job which stops itself.
89      *
90      * @return A list of descriptions.
91      */

92     public String JavaDoc[] activeDescriptions() {
93         List JavaDoc results = new ArrayList JavaDoc();
94         synchronized (activeThreads) {
95             for (Iterator JavaDoc it = activeThreads.entrySet().iterator(); it.hasNext(); ) {
96                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
97                 Thread JavaDoc t = (Thread JavaDoc) entry.getKey();
98                 if (!Thread.currentThread().equals(t)) {
99                     results.add( ((Remember)entry.getValue()).description );
100                 }
101             }
102             return (String JavaDoc[]) results.toArray(new String JavaDoc[0]);
103     
104         }
105     }
106     
107     public String JavaDoc toString() {
108         return "ThreadManager: " + activeThreads.size() + " active threads.";
109     }
110     
111     /**
112      * @return Returns the classLoader.
113      */

114     public ClassLoader JavaDoc getClassLoader() {
115         return classLoader;
116     }
117     /**
118      * @param classLoader The classLoader to set.
119      */

120     public void setClassLoader(ClassLoader JavaDoc classLoader) {
121         this.classLoader = classLoader;
122     }
123     
124     public void stopAll() {
125         synchronized (activeThreads) {
126             for (Iterator JavaDoc it = activeThreads.entrySet().iterator(); it.hasNext(); ) {
127                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
128                 Thread JavaDoc t = (Thread JavaDoc) entry.getKey();
129                 Remember r = (Remember) entry.getValue();
130                 if (r.runnable instanceof Stoppable) {
131                     ((Stoppable) r.runnable).stop();
132                 }
133                 else {
134                     if (!Thread.currentThread().equals(t)) {
135                         t.interrupt();
136                     }
137                 }
138             }
139         }
140     }
141     
142     class Remember {
143         private final String JavaDoc description;
144         private final Runnable JavaDoc runnable;
145         
146         Remember(String JavaDoc description, Runnable JavaDoc runnable) {
147             this.description = description;
148             this.runnable = runnable;
149         }
150     }
151 }
152
Popular Tags