1 /*
2 * Copyright (C) The Spice Group. All rights reserved.
3 *
4 * This software is published under the terms of the Spice
5 * Software License version 1.1, a copy of which has been included
6 * with this distribution in the LICENSE.txt file.
7 */
8 package org.jcomponent.threadpool.impl;
9
10 import org.apache.commons.pool.PoolableObjectFactory;
11 import org.apache.commons.pool.impl.GenericObjectPool;
12 import org.jcomponent.threadpool.ThreadPool;
13
14 /***
15 * The CommonsThreadPool is a component that provides a basic
16 * mechanism for pooling threads. A sample configuration for this
17 * component is;
18 * <pre>
19 * <config>
20 * <name>MyThreadPool</name> <!-- base name of all threads -->
21 * <priority>5</priority> <!-- set to default priority -->
22 * <is-daemon>false</is-daemon> <!-- are threads daemon threads? -->
23 * <resource-limiting>false</resource-limiting> <!-- will pool block when max threads reached? -->
24 * <max-threads>10</max-threads>
25 * <max-idle>5</max-idle> <!-- maximum number of idle threads -->
26 * </config>
27 * </pre>
28 *
29 * @author <a href="mailto:peter at realityforge.org">Peter Donald</a>
30 * @version $Revision: 1.7 $ $Date: 2003/08/31 00:50:23 $
31 */
32 public class CommonsThreadPool
33 extends AbstractThreadPool
34 implements ThreadPool, PoolableObjectFactory
35 {
36 /***
37 * The configuration 'struct' for our object pool.
38 */
39 private final GenericObjectPool.Config m_config = new GenericObjectPool.Config();
40
41 /***
42 * The underlying pool used to pool threads.
43 */
44 private GenericObjectPool m_pool;
45
46 /***
47 * Flag indicating whether component is disposed.
48 * If it is disposed it should not try to repool workers.
49 */
50 private boolean m_disposed;
51
52 /***
53 * The monitor that receives notifications of
54 * changes in pool.
55 */
56 private ThreadPoolMonitor m_monitor;
57
58 /***
59 * Initialize the underlying pool.
60 */
61 public void setup()
62 {
63 setThreadGroup( Thread.currentThread().getThreadGroup() );
64 m_monitor.newThreadPool( getName(),
65 getPriority(),
66 isDaemon(),
67 m_config.maxActive,
68 m_config.maxIdle );
69 m_pool = new GenericObjectPool( this, m_config );
70 setDisposeTime( 100 );
71 }
72
73 /***
74 * Shutdown all threads associated with pool.
75 */
76 public void shutdown()
77 {
78 shutdownInUseThreads();
79 m_disposed = true;
80 try
81 {
82 m_pool.close();
83 }
84 catch( final Exception e )
85 {
86 final String message = "Error closing pool: " + e;
87 m_monitor.unexpectedError( message, e );
88 }
89 }
90
91 /***
92 * Retrieve a worker thread from pool.
93 *
94 * @return the worker thread retrieved from pool
95 */
96 protected WorkerThread getWorker()
97 {
98 try
99 {
100 final WorkerThread worker = (WorkerThread)m_pool.borrowObject();
101 m_monitor.threadRetrieved( worker );
102 return worker;
103 }
104 catch( final Exception e )
105 {
106 m_monitor.unexpectedError( "Retrieving thread from pool", e );
107 return createWorker();
108 }
109 }
110
111 /***
112 * Return the WorkerThread to the pool.
113 *
114 * @param worker the worker thread to put back in pool
115 */
116 protected void releaseWorker( final WorkerThread worker )
117 {
118 if( m_disposed )
119 {
120 final String message =
121 "Ignoring attempt to return worker to " +
122 "disposed pool: " + worker.getName() +
123 ". Attempting dispose of worker.";
124 m_monitor.unexpectedError( message, null );
125 destroyWorker( worker );
126 return;
127 }
128
129 m_monitor.threadReturned( worker );
130 try
131 {
132 m_pool.returnObject( worker );
133 }
134 catch( final Exception e )
135 {
136 final String message =
137 "Returning '" + worker.getName() + "' To Pool";
138 m_monitor.unexpectedError( message, e );
139 }
140 }
141
142 /***
143 * Overide creation of worker to add logging.
144 *
145 * @return the new worker thread
146 */
147 protected WorkerThread createWorker()
148 {
149 final WorkerThread worker = super.createWorker();
150 m_monitor.threadCreated( worker );
151 return worker;
152 }
153
154 /***
155 * Overide destruction of worker to add logging.
156 *
157 * @param worker the worker thread
158 */
159 protected void destroyWorker( final WorkerThread worker )
160 {
161 m_monitor.threadDisposing( worker );
162 super.destroyWorker( worker );
163 }
164
165 /***
166 * Create a new worker. (Part of {@link PoolableObjectFactory} interface)
167 *
168 * @return the new worker
169 */
170 public Object makeObject()
171 {
172 return createWorker();
173 }
174
175 /***
176 * Destroy a worker. (Part of {@link PoolableObjectFactory} interface)
177 *
178 * @param worker the new worker
179 */
180 public void destroyObject( final Object worker )
181 {
182 destroyWorker( (WorkerThread)worker );
183 }
184
185 /***
186 * validate a worker. (Part of {@link PoolableObjectFactory} interface)
187 *
188 * @return true (no validation occurs)
189 */
190 public boolean validateObject( final Object worker )
191 {
192 return true;
193 }
194
195 /***
196 * activate a worker. (Part of {@link PoolableObjectFactory} interface)
197 * No-op.
198 */
199 public void activateObject( final Object worker )
200 {
201 }
202
203 /***
204 * passivate a worker. (Part of {@link PoolableObjectFactory} interface)
205 * No-op.
206 */
207 public void passivateObject( final Object worker )
208 {
209 }
210
211 /***
212 * Return the configuration object for Commons Pool.
213 *
214 * @return the configuration object for Commons Pool.
215 */
216 protected final GenericObjectPool.Config getCommonsConfig()
217 {
218 return m_config;
219 }
220
221 /***
222 * Set the Monitor to use to notify of changes in the Pool.
223 *
224 * @param monitor the Monitor to use to notify of changes in the Pool.
225 */
226 protected final void setMonitor( final ThreadPoolMonitor monitor )
227 {
228 m_monitor = monitor;
229 }
230 }
This page was automatically generated by Maven