View Javadoc

1   /*
2    * $Id: DefaultThreadPoolFactory.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.pool;
12  
13  import org.mule.api.MuleContext;
14  import org.mule.api.config.ThreadingProfile;
15  import org.mule.util.StringUtils;
16  import org.mule.util.concurrent.NamedThreadFactory;
17  import org.mule.util.concurrent.WaitPolicy;
18  
19  import edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue;
20  import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingDeque;
21  import edu.emory.mathcs.backport.java.util.concurrent.SynchronousQueue;
22  import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
23  import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  
27  /**
28  *
29  */
30  public class DefaultThreadPoolFactory extends ThreadPoolFactory
31  {
32      // deliberately shadow the superclass' static logger as to avoid log congestion on it
33      protected final Log logger = LogFactory.getLog(getClass());
34  
35      public ThreadPoolExecutor createPool(String name, ThreadingProfile tp)
36      {
37          BlockingQueue buffer;
38  
39          if (tp.getMaxBufferSize() > 0 && tp.getMaxThreadsActive() > 1)
40          {
41              buffer = new LinkedBlockingDeque(tp.getMaxBufferSize());
42          }
43          else
44          {
45              buffer = new SynchronousQueue();
46          }
47  
48          ThreadPoolExecutor pool = internalCreatePool(name, tp, buffer);
49          configureThreadFactory(name, tp, pool);
50  
51  
52          if (tp.getRejectedExecutionHandler() != null)
53          {
54              pool.setRejectedExecutionHandler(tp.getRejectedExecutionHandler());
55          }
56          else
57          {
58              switch (tp.getPoolExhaustedAction())
59              {
60                  case ThreadingProfile.WHEN_EXHAUSTED_DISCARD_OLDEST :
61                      pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
62                      break;
63                  case ThreadingProfile.WHEN_EXHAUSTED_RUN :
64                      pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
65                      break;
66                  case ThreadingProfile.WHEN_EXHAUSTED_ABORT :
67                      pool.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
68                      break;
69                  case ThreadingProfile.WHEN_EXHAUSTED_DISCARD :
70                      pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
71                      break;
72                  default :
73                      // WHEN_EXHAUSTED_WAIT
74                      pool.setRejectedExecutionHandler(new WaitPolicy(tp.getThreadWaitTimeout(), TimeUnit.MILLISECONDS));
75                      break;
76              }
77          }
78  
79          return pool;
80  
81      }
82  
83      protected void configureThreadFactory(String name, ThreadingProfile tp, ThreadPoolExecutor pool)
84      {
85          // use a custom ThreadFactory if one has been configured
86          if (tp.getThreadFactory() != null)
87          {
88              pool.setThreadFactory(tp.getThreadFactory());
89          }
90          else
91          {
92              // ..else create a "NamedThreadFactory" if a proper name was passed in
93              if (StringUtils.isNotBlank(name))
94              {
95                  // Use MuleContext classloader so that other temporary classloaders
96                  // aren't used when things are started lazily or from elsewhere.
97                  pool.setThreadFactory(new NamedThreadFactory(name, MuleContext.class.getClassLoader()));
98              }
99              else
100             {
101                 // let ThreadPoolExecutor create a default ThreadFactory;
102                 // see Executors.defaultThreadFactory()
103             }
104         }
105     }
106 
107     protected ThreadPoolExecutor internalCreatePool(String name, ThreadingProfile tp, BlockingQueue buffer)
108     {
109         return new ThreadPoolExecutor(Math.min(tp.getMaxThreadsIdle(), tp.getMaxThreadsActive()),
110                                       tp.getMaxThreadsActive(), tp.getThreadTTL(),
111                                       TimeUnit.MILLISECONDS, buffer);
112 
113     }
114 }