View Javadoc

1   /*
2    * $Id: ThreadingProfile.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.config;
12  
13  import org.mule.impl.work.MuleWorkManager;
14  import org.mule.umo.manager.UMOWorkManager;
15  import org.mule.util.MapUtils;
16  import org.mule.util.concurrent.NamedThreadFactory;
17  import org.mule.util.concurrent.WaitPolicy;
18  
19  import java.util.Map;
20  
21  import edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue;
22  import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingDeque;
23  import edu.emory.mathcs.backport.java.util.concurrent.RejectedExecutionHandler;
24  import edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue;
25  import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory;
26  import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
27  import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
28  import org.apache.commons.collections.map.CaseInsensitiveMap;
29  
30  /**
31   * <code>ThreadingProfile</code> is used to configure a thread pool. Mule uses a
32   * few different pools i.e. for component threads and message dispatchers. This object
33   * makes it easier to configure the pool.
34   */
35  
36  public class ThreadingProfile
37  {
38  
39      /**
40       * Default value for MAX_THREADS_ACTIVE
41       */
42      public static final int DEFAULT_MAX_THREADS_ACTIVE = 16;
43  
44      /**
45       * Default value for MAX_THREADS_IDLE
46       */
47      public static final int DEFAULT_MAX_THREADS_IDLE = 1;
48  
49      /**
50       * Default value for MAX_BUFFER_SIZE
51       */
52      public static final int DEFAULT_MAX_BUFFER_SIZE = 0;
53  
54      /**
55       * Default value for MAX_THREAD_TTL
56       */
57      public static final long DEFAULT_MAX_THREAD_TTL = 60000;
58  
59      /**
60       * Default value for DEFAULT_THREAD_WAIT_TIMEOUT
61       */
62      public static final long DEFAULT_THREAD_WAIT_TIMEOUT = 30000L;
63  
64      /**
65       * Default value for do threading
66       */
67      public static final boolean DEFAULT_DO_THREADING = true;
68  
69      /**
70       * Actions to perform on pool exhaustion
71       */
72      public static final int WHEN_EXHAUSTED_WAIT = 0;
73      public static final int WHEN_EXHAUSTED_DISCARD = 1;
74      public static final int WHEN_EXHAUSTED_DISCARD_OLDEST = 2;
75      public static final int WHEN_EXHAUSTED_ABORT = 3;
76      public static final int WHEN_EXHAUSTED_RUN = 4;
77  
78      /**
79       * Default action to perform on pool exhaustion
80       */
81      public static final int DEFAULT_POOL_EXHAUST_ACTION = WHEN_EXHAUSTED_RUN;
82  
83      // map pool exhaustion strings to their respective values
84      private static final Map POOL_EXHAUSTED_ACTIONS = new CaseInsensitiveMap()
85      {
86          private static final long serialVersionUID = 1L;
87  
88          // static initializer
89          {
90              Integer value = new Integer(WHEN_EXHAUSTED_WAIT);
91              this.put("WHEN_EXHAUSTED_WAIT", value);
92              this.put("WAIT", value);
93  
94              value = new Integer(WHEN_EXHAUSTED_DISCARD);
95              this.put("WHEN_EXHAUSTED_DISCARD", value);
96              this.put("DISCARD", value);
97  
98              value = new Integer(WHEN_EXHAUSTED_DISCARD_OLDEST);
99              this.put("WHEN_EXHAUSTED_DISCARD_OLDEST", value);
100             this.put("DISCARD_OLDEST", value);
101 
102             value = new Integer(WHEN_EXHAUSTED_ABORT);
103             this.put("WHEN_EXHAUSTED_ABORT", value);
104             this.put("ABORT", value);
105 
106             value = new Integer(WHEN_EXHAUSTED_RUN);
107             this.put("WHEN_EXHAUSTED_RUN", value);
108             this.put("RUN", value);
109         }
110     };
111 
112     private int maxThreadsActive = DEFAULT_MAX_THREADS_ACTIVE;
113     private int maxThreadsIdle = DEFAULT_MAX_THREADS_IDLE;
114     private int maxBufferSize = DEFAULT_MAX_BUFFER_SIZE;
115     private long threadTTL = DEFAULT_MAX_THREAD_TTL;
116     private long threadWaitTimeout = DEFAULT_THREAD_WAIT_TIMEOUT;
117     private int poolExhaustPolicy = DEFAULT_POOL_EXHAUST_ACTION;
118     private boolean doThreading = DEFAULT_DO_THREADING;
119 
120     private WorkManagerFactory workManagerFactory = new DefaultWorkManagerFactory();
121 
122     private RejectedExecutionHandler rejectedExecutionHandler;
123 
124     private ThreadFactory threadFactory;
125 
126     public ThreadingProfile()
127     {
128         super();
129     }
130 
131     public ThreadingProfile(int maxThreadsActive,
132                             int maxThreadsIdle,
133                             long threadTTL,
134                             int poolExhaustPolicy,
135                             RejectedExecutionHandler rejectedExecutionHandler,
136                             ThreadFactory threadFactory)
137     {
138         this.maxThreadsActive = maxThreadsActive;
139         this.maxThreadsIdle = maxThreadsIdle;
140         this.threadTTL = threadTTL;
141         this.poolExhaustPolicy = poolExhaustPolicy;
142         this.rejectedExecutionHandler = rejectedExecutionHandler;
143         this.threadFactory = threadFactory;
144     }
145 
146     public ThreadingProfile(ThreadingProfile tp)
147     {
148         this.maxThreadsActive = tp.getMaxThreadsActive();
149         this.maxThreadsIdle = tp.getMaxThreadsIdle();
150         this.maxBufferSize = tp.getMaxBufferSize();
151         this.threadTTL = tp.getThreadTTL();
152         this.threadWaitTimeout = tp.getThreadWaitTimeout();
153         this.poolExhaustPolicy = tp.getPoolExhaustedAction();
154         this.doThreading = tp.isDoThreading();
155         this.rejectedExecutionHandler = tp.getRejectedExecutionHandler();
156         this.threadFactory = tp.getThreadFactory();
157         this.workManagerFactory = tp.getWorkManagerFactory();
158     }
159 
160     public int getMaxThreadsActive()
161     {
162         return maxThreadsActive;
163     }
164 
165     public int getMaxThreadsIdle()
166     {
167         return maxThreadsIdle;
168     }
169 
170     public long getThreadTTL()
171     {
172         return threadTTL;
173     }
174 
175     public long getThreadWaitTimeout()
176     {
177         return threadWaitTimeout;
178     }
179 
180     public int getPoolExhaustedAction()
181     {
182         return poolExhaustPolicy;
183     }
184 
185     public RejectedExecutionHandler getRejectedExecutionHandler()
186     {
187         return rejectedExecutionHandler;
188     }
189 
190     public ThreadFactory getThreadFactory()
191     {
192         return threadFactory;
193     }
194 
195     public void setMaxThreadsActive(int maxThreadsActive)
196     {
197         this.maxThreadsActive = maxThreadsActive;
198     }
199 
200     public void setMaxThreadsIdle(int maxThreadsIdle)
201     {
202         this.maxThreadsIdle = maxThreadsIdle;
203     }
204 
205     public void setThreadTTL(long threadTTL)
206     {
207         this.threadTTL = threadTTL;
208     }
209 
210     public void setThreadWaitTimeout(long threadWaitTimeout)
211     {
212         this.threadWaitTimeout = threadWaitTimeout;
213     }
214 
215     public void setPoolExhaustedAction(int poolExhaustPolicy)
216     {
217         this.poolExhaustPolicy = poolExhaustPolicy;
218     }
219 
220     public void setPoolExhaustedActionString(String poolExhaustPolicy)
221     {
222         this.poolExhaustPolicy = MapUtils.getIntValue(POOL_EXHAUSTED_ACTIONS, poolExhaustPolicy,
223             DEFAULT_POOL_EXHAUST_ACTION);
224     }
225 
226     public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler)
227     {
228         this.rejectedExecutionHandler = rejectedExecutionHandler;
229     }
230 
231     public void setThreadFactory(ThreadFactory threadFactory)
232     {
233         this.threadFactory = threadFactory;
234     }
235 
236     public int getMaxBufferSize()
237     {
238         return maxBufferSize;
239     }
240 
241     public void setMaxBufferSize(int maxBufferSize)
242     {
243         this.maxBufferSize = maxBufferSize;
244     }
245 
246     public WorkManagerFactory getWorkManagerFactory()
247     {
248         return workManagerFactory;
249     }
250 
251     public void setWorkManagerFactory(WorkManagerFactory workManagerFactory)
252     {
253         this.workManagerFactory = workManagerFactory;
254     }
255 
256     public UMOWorkManager createWorkManager(String name)
257     {
258         return workManagerFactory.createWorkManager(this, name);
259     }
260 
261     public ThreadPoolExecutor createPool()
262     {
263         return createPool(null);
264     }
265 
266     public ThreadPoolExecutor createPool(String name)
267     {
268         BlockingQueue buffer;
269 
270         if (maxBufferSize > 0 && maxThreadsActive > 1)
271         {
272             buffer = new LinkedBlockingDeque(maxBufferSize);
273         }
274         else
275         {
276             buffer = new SynchronousQueue();
277         }
278 
279         if (maxThreadsIdle > maxThreadsActive)
280         {
281             maxThreadsIdle = maxThreadsActive;
282         }
283 
284         ThreadPoolExecutor pool = new ThreadPoolExecutor(maxThreadsIdle, maxThreadsActive, threadTTL,
285             TimeUnit.MILLISECONDS, buffer);
286 
287         ThreadFactory tf = threadFactory;
288         if (name != null)
289         {
290             tf = new NamedThreadFactory(name); 
291         }
292 
293         if (tf != null)
294         {
295             pool.setThreadFactory(tf);
296         }
297 
298         if (rejectedExecutionHandler != null)
299         {
300             pool.setRejectedExecutionHandler(rejectedExecutionHandler);
301         }
302         else
303         {
304             switch (poolExhaustPolicy)
305             {
306                 case WHEN_EXHAUSTED_DISCARD_OLDEST :
307                     pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
308                     break;
309                 case WHEN_EXHAUSTED_RUN :
310                     pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
311                     break;
312                 case WHEN_EXHAUSTED_ABORT :
313                     pool.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
314                     break;
315                 case WHEN_EXHAUSTED_DISCARD :
316                     pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
317                     break;
318                 default :
319                     // WHEN_EXHAUSTED_WAIT
320                     pool.setRejectedExecutionHandler(new WaitPolicy(threadWaitTimeout, TimeUnit.MILLISECONDS));
321                     break;
322             }
323         }
324 
325         return pool;
326     }
327 
328     public boolean isDoThreading()
329     {
330         return doThreading;
331     }
332 
333     public void setDoThreading(boolean doThreading)
334     {
335         this.doThreading = doThreading;
336     }
337 
338     public String toString()
339     {
340         return "ThreadingProfile{" + "maxThreadsActive=" + maxThreadsActive + ", maxThreadsIdle="
341                         + maxThreadsIdle + ", maxBufferSize=" + maxBufferSize + ", threadTTL=" + threadTTL
342                         + ", poolExhaustPolicy=" + poolExhaustPolicy + ", threadWaitTimeout="
343                         + threadWaitTimeout + ", doThreading=" + doThreading + ", workManagerFactory="
344                         + workManagerFactory + ", rejectedExecutionHandler=" + rejectedExecutionHandler
345                         + ", threadFactory=" + threadFactory + "}";
346     }
347 
348     public static interface WorkManagerFactory
349     {
350         UMOWorkManager createWorkManager(ThreadingProfile profile, String name);
351     }
352 
353     private class DefaultWorkManagerFactory implements WorkManagerFactory
354     {
355         public UMOWorkManager createWorkManager(ThreadingProfile profile, String name)
356         {
357             return new MuleWorkManager(profile, name);
358         }
359     }
360 
361 }