You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by fe...@apache.org on 2007/03/27 17:10:40 UTC
svn commit: r522946 [2/2] - in /cocoon/trunk/core/cocoon-thread:
cocoon-thread-api/src/changes/
cocoon-thread-api/src/main/java/org/apache/cocoon/components/thread/
cocoon-thread-impl/ cocoon-thread-impl/src/changes/
cocoon-thread-impl/src/main/java/or...
Modified: cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/main/java/org/apache/cocoon/components/thread/DefaultThreadPool.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/main/java/org/apache/cocoon/components/thread/DefaultThreadPool.java?view=diff&rev=522946&r1=522945&r2=522946
==============================================================================
--- cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/main/java/org/apache/cocoon/components/thread/DefaultThreadPool.java (original)
+++ cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/main/java/org/apache/cocoon/components/thread/DefaultThreadPool.java Tue Mar 27 08:10:39 2007
@@ -18,289 +18,604 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
-
/**
* The DefaultThreadPool class implements the {@link ThreadPool} interface.
* Instances of this class are made by the {@link RunnableManager} passing a
- * configuration into the <code>configure</code> method.
- *
+ * threadpool into the <code>init</code> method.
+ *
+ * <pre>
+ * <!--+
+ * | More indepth information can be found at
+ * | http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/PooledExecutor.html
+ * | The following elements can be used:
+ * +-->
+ * <!-- required name of the pool -->
+ * <property name="name" value="default" />
+ * <!--+
+ * | optional priority all threads of the pool will have (the ThreadFactory will be
+ * | set to this priority).The possible values are:
+ * | MIN: corresponds to Thread#MIN_PRIORITY
+ * | NORM: corresponds to Thread#NORM_PRIORITY (default)
+ * | MAX: corresponds to Thread#MAX_PRIORITY
+ * +-->
+ * <property name="poolPriority" value="NORM" />
+ * <!--+
+ * | whether newly created Threads should run in daemon mode or not. Default to false.
+ * +-->
+ * <property name="daemon" value="false" />
+ * <!--+
+ * | optional size of a queue to hold Runnables if the pool is full. Possible values are:
+ * | less than 0: unbounded (default)
+ * | equal to 0: no queue at all
+ * | greater than 0: size of the queue
+ * -->
+ * <property name="queueSize" value="-1" />
+ * <!--+
+ * | optional maximum number of threads in the pool. Defaults to 5.
+ * | NOTE: if a queue is specified (queue-sie != 0)
+ * | this value will be ignored.
+ * +-->
+ * <property name="maxPoolSize" value="5" />
+ * <!--+
+ * | optional minimum number of threads in the pool. Defaults to 5.
+ * | NOTE: if a queue has been specified (queue-sie != 0)
+ * | this value will be used as the maximum of thread running concurrently.
+ * +-->
+ * <property name="minPoolSize" value="5" />
+ * <!--+
+ * | The time in ms an idle thread should keep alive before it might get garbage collected.
+ * | This defaults to 60000 ms.
+ * +-->
+ * <property name="keepAliveTime" value="60000" />
+ * <!--+
+ * | The policy to be used if all resources (thread in the pool and
+ * | slots in the queue) are exhausted.
+ * | Possible values are:
+ * | ABORT: Throw a RuntimeException
+ * | DISCARD: Throw away the current request and return.
+ * | DISCARDOLDEST: Throw away the oldest request and return.
+ * | RUN (default): The thread making the execute request runs the task itself.
+ * | This policy helps guard against lockup.
+ * | WAIT: Wait until a thread becomes available. This policy should, in
+ * | general, not be used if the minimum number of threads is zero,
+ * | in which case a thread may never become available.
+ * +-->
+ * <property name="blockPolicy" value="ABORT" />
+ * <!--+
+ * | Terminate thread pool after processing all Runnables currently in queue. Any
+ * | Runnable entered after this point will be discarded. A shut down pool cannot
+ * | be restarted. This also means that a pool will need keep-alive-time-ms to
+ * | terminate. The default value not to shutdown graceful.
+ * +-->
+ * <property name="shutdownGraceful" value="false" />
+ * <!--+
+ * | The time in ms to wait before issuing an immediate shutdown after a graceful shutdown
+ * | has been requested.
+ * +-->
+ * <property name="shutdownWaitTimeMs" value="-1" />
+ * <!--+
+ * | specifies the fully qualified class name of an org.apache.cocoon.components.thread.ThreadFactory
+ * | implementation. It is responsible to create Thread classes.
+ * +-->
+ * <property name="factory" ref="defaultThreadFactory"/>
+ * </pre>
+ *
* @version $Id$
*/
-public class DefaultThreadPool
- extends PooledExecutor
- implements ThreadPool {
+public class DefaultThreadPool extends PooledExecutor implements
+ InitializingBean, ThreadPool {
- //~ Static fields/initializers ---------------------------------------------
+ // ~ Static fields/initializers
+ // ---------------------------------------------
/** Default ThreadPool block policy */
public static final String POLICY_DEFAULT = POLICY_RUN;
- //~ Instance fields --------------------------------------------------------
-
- /** Wrapps a channel */
- private ChannelWrapper channelWrapper;
-
/** By default we use the logger for this class. */
- private Log logger = LogFactory.getLog(getClass());
-
- /** The Queue */
- private Queue queue;
+ protected final Log logger = LogFactory.getLog(getClass());
- /** The blocking policy */
- private String blockPolicy;
+ // ~ Instance fields
+ // --------------------------------------------------------
/** The name of this thread pool */
- private String name;
+ private String name = ThreadPool.DEFAULT_THREADPOOL_NAME;
- /** Should we wait for running jobs to terminate on shutdown ? */
- private boolean shutdownGraceful;
+ /** Is daemon thread pool */
+ private boolean daemon = ThreadPool.DEFAULT_DAEMON_MODE;
+
+ /** The priority of this thread pool */
+ private int priority = convertPriority(ThreadPool.DEFAULT_THREAD_PRIORITY);
/** The maximum queue size */
- private int queueSize;
+ private int queueSize = ThreadPool.DEFAULT_QUEUE_SIZE;
+
+ /** The maximum pool size */
+ private int maxPoolSize = ThreadPool.DEFAULT_MAX_POOL_SIZE;
+
+ /** The minimum pool size */
+ private int minPoolSize = ThreadPool.DEFAULT_MIN_POOL_SIZE;
+
+ /** The keep alive time in milliseconds */
+ private long keepAliveTime = ThreadPool.DEFAULT_KEEP_ALIVE_TIME;
+
+ /** The blocking policy */
+ private String blockPolicy = ThreadPool.DEFAULT_BLOCK_POLICY;
+
+ /** Should we wait for running jobs to terminate on shutdown ? */
+ private boolean shutdownGraceful = ThreadPool.DEFAULT_SHUTDOWN_GRACEFUL;
/** How long to wait for running jobs to terminate on disposition */
- private int shutdownWaitTimeMs;
+ private int shutdownWaitTimeMs = ThreadPool.DEFAULT_SHUTDOWN_WAIT_TIME;
+
+ /** A ThreadFactory implementation */
+ private ThreadFactory factory;
+
+ /** Wrapps a channel */
+ private ChannelWrapper channelWrapper;
+
+ /** The Queue */
+ private Queue queue;
- //~ Constructors -----------------------------------------------------------
+ // ~ Constructors
+ // -----------------------------------------------------------
/**
- * Create a new pool.
- */
- DefaultThreadPool() {
- this( new ChannelWrapper() );
+ * Create a new pool.
+ *
+ * @param channel
+ * DOCUMENT ME!
+ */
+ private DefaultThreadPool(final ChannelWrapper channel) {
+ super(channel);
+ channelWrapper = channel;
}
/**
- * Create a new pool.
- *
- * @param channel DOCUMENT ME!
- */
- private DefaultThreadPool( final ChannelWrapper channel ) {
- super( channel );
- channelWrapper = channel;
+ * Create a new pool.
+ */
+ DefaultThreadPool() {
+ this(new ChannelWrapper());
}
- //~ Methods ----------------------------------------------------------------
-
- public Log getLogger() {
- return this.logger;
- }
+ // ~ Methods
+ // ----------------------------------------------------------------
- public void setLogger(Log l) {
- this.logger = l;
+ /** Initialize the bean after properties set */
+ public void afterPropertiesSet() throws IllegalArgumentException {
+ if (logger.isInfoEnabled()) {
+ logger.info("ThreadPool [" + name + "] initializing ...");
+ }
+
+ initFactory();
+ super.setThreadFactory(factory);
+ initMinPoolSize();
+ initPriority();
+ initDaemon();
+ initQueueSize();
+ initMaxPoolSize();
+ initKeepAliveTime();
+
+ if (logger.isInfoEnabled()) {
+ logger.info(this.toString());
+ logger.info("ThreadPool [" + name + "] initialized");
+ }
}
/**
- * DOCUMENT ME!
- *
- * @return Returns the blockPolicy.
- */
+ * Get the block policy
+ *
+ * @return Returns the blockPolicy.
+ */
public String getBlockPolicy() {
- return blockPolicy;
+ return blockPolicy;
}
/**
- * DOCUMENT ME!
- *
- * @return maximum size of the queue (0 if isQueued() == false)
- *
- * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize()
- */
+ * DOCUMENT ME!
+ *
+ * @return maximum size of the queue (0 if isQueued() == false)
+ *
+ * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize()
+ */
public int getMaxQueueSize() {
- return ( ( queueSize < 0 ) ? Integer.MAX_VALUE : queueSize );
- }
-
- /**
- * DOCUMENT ME!
- *
- * @return size of queue (0 if isQueued() == false)
- *
- * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize()
- */
- public int getMaximumQueueSize() {
- return queueSize;
+ return ((queueSize < 0) ? Integer.MAX_VALUE : queueSize);
}
/**
- * @see org.apache.cocoon.components.thread.ThreadPool#getName()
- */
+ * @see org.apache.cocoon.components.thread.ThreadPool#getName()
+ */
public String getName() {
- return name;
+ return name;
}
/**
- * Get hte priority used to create Threads
- *
- * @return {@link Thread#MIN_PRIORITY}, {@link Thread#NORM_PRIORITY}, or
- * {@link Thread#MAX_PRIORITY}
- */
+ * Get hte priority used to create Threads
+ *
+ * @return {@link Thread#MIN_PRIORITY}, {@link Thread#NORM_PRIORITY},
+ * or {@link Thread#MAX_PRIORITY}
+ */
public int getPriority() {
- return ((ThreadFactory)super.getThreadFactory()).getPriority();
+ return ((ThreadFactory) super.getThreadFactory()).getPriority();
}
/**
- * DOCUMENT ME!
- *
- * @return current size of the queue (0 if isQueued() == false)
- *
- * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize()
- */
+ * DOCUMENT ME!
+ *
+ * @return current size of the queue (0 if isQueued() == false)
+ *
+ * @see org.apache.cocoon.components.thread.ThreadPool#getQueueSize()
+ */
public int getQueueSize() {
- return queue.getQueueSize();
+ return queue.getQueueSize();
}
/**
- * Whether this DefaultThreadPool has a queue
- *
- * @return Returns the m_isQueued.
- *
- * @see org.apache.cocoon.components.thread.ThreadPool#isQueued()
- */
+ * Whether this DefaultThreadPool has a queue
+ *
+ * @return Returns the m_isQueued.
+ *
+ * @see org.apache.cocoon.components.thread.ThreadPool#isQueued()
+ */
public boolean isQueued() {
- return queueSize != 0;
+ return queueSize != 0;
}
/**
- * Execute a command
- *
- * @param command The {@link Runnable} to execute
- *
- * @throws InterruptedException In case of interruption
- */
- public void execute( Runnable command ) throws InterruptedException {
- if( getLogger().isDebugEnabled() ) {
- getLogger().debug( "Executing Command: " + command.toString() +
- ",pool=" + getName() );
- }
+ * Execute a command
+ *
+ * @param command
+ * The {@link Runnable} to execute
+ *
+ * @throws InterruptedException
+ * In case of interruption
+ */
+ public void execute(Runnable command) throws InterruptedException {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Executing Command: " + command.toString() + ",pool="
+ + getName());
+ }
- super.execute( command );
+ super.execute(command);
}
/**
- * @see org.apache.cocoon.components.thread.ThreadPool#shutdown()
- */
+ * @see org.apache.cocoon.components.thread.ThreadPool#shutdown()
+ */
public void shutdown() {
- if( shutdownGraceful ) {
- shutdownAfterProcessingCurrentlyQueuedTasks();
- } else {
- shutdownNow();
- }
-
- try {
- if( getShutdownWaitTimeMs() > 0 ) {
- if( ! awaitTerminationAfterShutdown( getShutdownWaitTimeMs()) ) {
- getLogger().warn( "running commands have not terminated within " +
- getShutdownWaitTimeMs() +
- "ms. Will shut them down by interruption" );
- interruptAll();
- shutdownNow();
- }
- }
-
- awaitTerminationAfterShutdown();
- } catch( final InterruptedException ie ) {
- getLogger().error( "cannot shutdown ThreadPool", ie );
- }
- }
-
- /**
- * Set the blocking policy
- *
- * @param blockPolicy The blocking policy value
- */
- void setBlockPolicy( final String blockPolicy ) {
- this.blockPolicy = blockPolicy;
-
- if( POLICY_ABORT.equalsIgnoreCase( blockPolicy ) ) {
- abortWhenBlocked( );
- } else if( POLICY_DISCARD.equalsIgnoreCase( blockPolicy ) ) {
- discardWhenBlocked( );
- } else if( POLICY_DISCARD_OLDEST.equalsIgnoreCase( blockPolicy ) ) {
- discardOldestWhenBlocked();
- } else if( POLICY_RUN.equalsIgnoreCase( blockPolicy ) ) {
- runWhenBlocked();
- } else if( POLICY_WAIT.equalsIgnoreCase( blockPolicy ) ) {
- waitWhenBlocked();
- } else {
- final StringBuffer msg = new StringBuffer();
- msg.append( "WARNING: Unknown block-policy configuration \"" )
- .append( blockPolicy );
- msg.append( "\". Should be one of \"" ).append( POLICY_ABORT );
- msg.append( "\",\"" ).append( POLICY_DISCARD );
- msg.append( "\",\"" ).append( POLICY_DISCARD_OLDEST );
- msg.append( "\",\"" ).append( POLICY_RUN );
- msg.append( "\",\"" ).append( POLICY_WAIT );
- msg.append( "\". Will use \"" ).append( POLICY_DEFAULT ).append( "\"" );
- getLogger().warn( msg.toString() );
- setBlockPolicy( POLICY_DEFAULT );
- }
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param name The name to set.
- */
- void setName( String name ) {
- this.name = name;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param queueSize DOCUMENT ME!
- */
- void setQueue( final int queueSize ) {
- if( queueSize != 0 ) {
- if( queueSize > 0 ) {
- queue = new BoundedQueue( queueSize );
- } else {
- queue = new LinkedQueue( );
- }
- } else {
- queue = new SynchronousChannel( );
- }
-
- this.queueSize = queueSize;
- channelWrapper.setChannel( queue );
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param shutdownGraceful The shutdownGraceful to set.
- */
- void setShutdownGraceful( boolean shutdownGraceful ) {
- this.shutdownGraceful = shutdownGraceful;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @return Returns the shutdownGraceful.
- */
- boolean isShutdownGraceful() {
- return shutdownGraceful;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param shutdownWaitTimeMs The shutdownWaitTimeMs to set.
- */
- void setShutdownWaitTimeMs( int shutdownWaitTimeMs ) {
- this.shutdownWaitTimeMs = shutdownWaitTimeMs;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @return Returns the shutdownWaitTimeMs.
- */
- int getShutdownWaitTimeMs() {
- return shutdownWaitTimeMs;
+ if (shutdownGraceful) {
+ shutdownAfterProcessingCurrentlyQueuedTasks();
+ } else {
+ shutdownNow();
+ }
+
+ try {
+ if (getShutdownWaitTimeMs() > 0) {
+ if (!awaitTerminationAfterShutdown(getShutdownWaitTimeMs())) {
+ logger.warn("running commands have not terminated within "
+ + getShutdownWaitTimeMs()
+ + "ms. Will shut them down by interruption");
+ interruptAll();
+ shutdownNow();
+ }
+ }
+
+ awaitTerminationAfterShutdown();
+ } catch (final InterruptedException ie) {
+ logger.error("cannot shutdown ThreadPool", ie);
+ }
+ }
+
+ /**
+ * Set the blocking policy
+ *
+ * @param blockPolicy
+ * The blocking policy value
+ */
+ public void setBlockPolicy(final String blockPolicy) {
+ this.blockPolicy = blockPolicy;
+
+ if (POLICY_ABORT.equalsIgnoreCase(blockPolicy)) {
+ abortWhenBlocked();
+ } else if (POLICY_DISCARD.equalsIgnoreCase(blockPolicy)) {
+ discardWhenBlocked();
+ } else if (POLICY_DISCARD_OLDEST.equalsIgnoreCase(blockPolicy)) {
+ discardOldestWhenBlocked();
+ } else if (POLICY_RUN.equalsIgnoreCase(blockPolicy)) {
+ runWhenBlocked();
+ } else if (POLICY_WAIT.equalsIgnoreCase(blockPolicy)) {
+ waitWhenBlocked();
+ } else {
+ final StringBuffer msg = new StringBuffer();
+ msg.append("WARNING: Unknown block-policy configuration \"")
+ .append(blockPolicy);
+ msg.append("\". Should be one of \"").append(POLICY_ABORT);
+ msg.append("\",\"").append(POLICY_DISCARD);
+ msg.append("\",\"").append(POLICY_DISCARD_OLDEST);
+ msg.append("\",\"").append(POLICY_RUN);
+ msg.append("\",\"").append(POLICY_WAIT);
+ msg.append("\". Will use \"").append(POLICY_DEFAULT).append("\"");
+ logger.warn(msg.toString());
+ setBlockPolicy(POLICY_DEFAULT);
+ }
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param name
+ * The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param shutdownGraceful
+ * The shutdownGraceful to set.
+ */
+ public void setShutdownGraceful(boolean shutdownGraceful) {
+ this.shutdownGraceful = shutdownGraceful;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @return Returns the shutdownGraceful.
+ */
+ public boolean isShutdownGraceful() {
+ return shutdownGraceful;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param shutdownWaitTimeMs
+ * The shutdownWaitTimeMs to set.
+ */
+ public void setShutdownWaitTimeMs(int shutdownWaitTimeMs) {
+ this.shutdownWaitTimeMs = shutdownWaitTimeMs;
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @return Returns the shutdownWaitTimeMs.
+ */
+ public int getShutdownWaitTimeMs() {
+ return shutdownWaitTimeMs;
+ }
+
+ /**
+ * @return the keepAliveTime
+ */
+ public long getKeepAliveTime() {
+ return keepAliveTime;
+ }
+
+ /**
+ * @param keepAliveTime
+ * the keepAliveTime to set
+ */
+ public void setKeepAliveTime(long keepAliveTime) {
+ this.keepAliveTime = keepAliveTime;
+ }
+
+ /**
+ * @return the maxPoolSize
+ */
+ public int getMaxPoolSize() {
+ return maxPoolSize;
+ }
+
+ /**
+ * @param maxPoolSize
+ * the maxPoolSize to set
+ */
+ public void setMaxPoolSize(int maxPoolSize) {
+ this.maxPoolSize = maxPoolSize;
+ }
+
+ /**
+ * @return the minPoolSize
+ */
+ public int getMinPoolSize() {
+ return minPoolSize;
+ }
+
+ /**
+ * @param minPoolSize
+ * the minPoolSize to set
+ */
+ public void setMinPoolSize(int minPoolSize) {
+ this.minPoolSize = minPoolSize;
+ }
+
+ /**
+ * @return the threadFactory
+ */
+ public ThreadFactory getFactory() {
+ return factory;
+ }
+
+ /**
+ * @param priority
+ * the priority to set
+ */
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+ /**
+ * @param pool
+ * priority the priority to set
+ */
+ public void setPoolPriority(String poolPriority) {
+ setPriority(convertPriority(poolPriority));
+ }
+
+ /**
+ * Sets the queue size of the thread pool
+ *
+ * @param queueSize
+ * the queueSize to set
+ */
+ public void setQueueSize(int queueSize) {
+ this.queueSize = queueSize;
+ }
+
+ /**
+ * Returns true if thread runs as daemon
+ *
+ * @return the daemon
+ */
+ public boolean isDaemon() {
+ return daemon;
+ }
+
+ /**
+ * Set to true if thread shall run as daemon
+ *
+ * @param daemon
+ * the daemon to set
+ */
+ public void setDaemon(boolean daemon) {
+ this.daemon = daemon;
+ }
+
+ /**
+ * Overwrite the toString method
+ */
+ public String toString() {
+ if (this.isQueued()) {
+ final StringBuffer msg = new StringBuffer();
+ msg.append("ThreadPool named \"").append(name);
+ msg.append("\" created with maximum queue-size=").append(queueSize);
+ msg.append(",max-pool-size=").append(maximumPoolSize_);
+ msg.append(",min-pool-size=").append(minimumPoolSize_);
+ msg.append(",priority=").append(priority);
+ msg.append(",isDaemon=").append(
+ ((ThreadFactory) this.getThreadFactory()).isDaemon());
+ msg.append(",keep-alive-time-ms=").append(keepAliveTime_);
+ msg.append(",block-policy=\"").append(blockPolicy);
+ msg.append("\",shutdown-wait-time-ms=").append(shutdownWaitTimeMs);
+ return msg.toString();
+ } else {
+ final StringBuffer msg = new StringBuffer();
+ msg.append("ThreadPool named \"").append(name);
+ msg.append("\" created with no queue,max-pool-size=").append(
+ maximumPoolSize_);
+ msg.append(",min-pool-size=").append(minimumPoolSize_);
+ msg.append(",priority=").append(priority);
+ msg.append(",isDaemon=").append(
+ ((ThreadFactory) this.getThreadFactory()).isDaemon());
+ msg.append(",keep-alive-time-ms=").append(keepAliveTime_);
+ msg.append(",block-policy=").append(blockPolicy);
+ msg.append(",shutdown-wait-time-ms=").append(shutdownWaitTimeMs);
+ return msg.toString();
+ }
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param priority
+ * The priority to set as string value.
+ *
+ * @return The priority as int value.
+ */
+ private int convertPriority(final String priority) {
+ if ("MIN".equalsIgnoreCase(priority)) {
+ return Thread.MIN_PRIORITY;
+ } else if ("NORM".equalsIgnoreCase(priority)) {
+ return Thread.NORM_PRIORITY;
+ } else if ("MAX".equalsIgnoreCase(priority)) {
+ return Thread.MAX_PRIORITY;
+ } else {
+ logger.warn("Unknown thread priority \"" + priority
+ + "\". Set to \"NORM\".");
+
+ return Thread.NORM_PRIORITY;
+ }
+ }
+
+ /**
+ * @param factory
+ * the factory to set
+ */
+ public void setFactory(ThreadFactory factory) {
+ this.factory = factory;
+ }
+
+ private void initFactory() {
+ if (factory == null) {
+ logger.warn("No ThreadFactory is configured. Will use a "
+ + DefaultThreadFactory.class.getName());
+ factory = new org.apache.cocoon.components.thread.DefaultThreadFactory();
+ }
+ }
+
+ private void initMinPoolSize() {
+ // Min pool size
+ // make sure we have enough threads for the default thread pool as we
+ // need one for ourself
+ if (ThreadPool.DEFAULT_THREADPOOL_NAME.equals(name)
+ && ((minPoolSize > 0) && (minPoolSize < ThreadPool.DEFAULT_MIN_POOL_SIZE))) {
+ minPoolSize = ThreadPool.DEFAULT_MIN_POOL_SIZE;
+ }
+ if (minPoolSize < 1) {
+ minPoolSize = (minPoolSize < 1) ? 1 : minPoolSize;
+ logger
+ .warn("min-pool-size < 1 for pool \"" + name
+ + "\". Set to 1");
+ }
+ super.setMinimumPoolSize(minPoolSize);
+ }
+
+ private void initPriority() {
+ // Use priority from factory when changed
+ priority = (factory.getPriority() != Thread.NORM_PRIORITY ? factory
+ .getPriority() : priority);
+ factory.setPriority(priority);
+ }
+
+ private void initDaemon() {
+ // Use daemon from factory when changed
+ daemon = (factory.isDaemon() != false ? factory.isDaemon() : daemon);
+ factory.setDaemon(daemon);
+ }
+
+ private void initMaxPoolSize() {
+ // Max pool size
+ maxPoolSize = (maxPoolSize < 0) ? Integer.MAX_VALUE : maxPoolSize;
+ super.setMaximumPoolSize(maxPoolSize);
+ }
+
+ private void initKeepAliveTime() {
+ // Keep alive time
+ if (keepAliveTime < 0) {
+ keepAliveTime = 1000;
+ logger.warn("keep-alive-time-ms < 0 for pool \"" + name
+ + "\". Set to 1000");
+ }
+ super.setKeepAliveTime(keepAliveTime);
+ }
+
+ private void initQueueSize() {
+ if (queueSize != 0) {
+ if (queueSize > 0) {
+ queue = new BoundedQueue(queueSize);
+ } else {
+ queue = new LinkedQueue();
+ }
+ } else {
+ queue = new SynchronousChannel();
+ }
+ channelWrapper.setChannel(queue);
}
}
Modified: cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/main/resources/META-INF/cocoon/spring/cocoon-thread-impl.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/main/resources/META-INF/cocoon/spring/cocoon-thread-impl.xml?view=diff&rev=522946&r1=522945&r2=522946
==============================================================================
--- cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/main/resources/META-INF/cocoon/spring/cocoon-thread-impl.xml (original)
+++ cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/main/resources/META-INF/cocoon/spring/cocoon-thread-impl.xml Tue Mar 27 08:10:39 2007
@@ -19,8 +19,10 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:configurator="http://cocoon.apache.org/schema/configurator"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
+ http://cocoon.apache.org/schema/configurator http://cocoon.apache.org/schema/configurator/cocoon-configurator-1.0.1.xsd">
<!--+
| Runnable manager
@@ -30,108 +32,118 @@
+-->
<bean name="org.apache.cocoon.components.thread.RunnableManager"
class="org.apache.cocoon.components.thread.DefaultRunnableManager"
- scope="singleton" init-method="init" destroy-method="destroy">
+ scope="singleton" destroy-method="destroy">
<!--+
| This is the default configuration of the runnable-manager. More
| indepth information can be found at
| http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/PooledExecutor.html
| The following elements can be used:
|
- | thread-factory: specifies the fully qualified class name of an
- | org.apache.cocoon.components.thread.ThreadFactory
- | implementation. It is responsible to create Thread
- | classes.
- | thread-pools: container element for thread-pool elements.
- | name: required name of the pool.
- | priority: optional priority all threads of the pool will
- | have (the ThreadFactory will be set to this
- | priority).The possible values are:
- | MIN: corresponds to Thread#MIN_PRIORITY
- | NORM: corresponds to Thread#NORM_PRIORITY (default)
- | MAX: corresponds to Thread#MAX_PRIORITY
- | daemon: whether newly created Threads should run in
- | daemon mode or not. Default to false.
- | queue-size: optional size of a queue to hold Runnables if the
- | pool is full. Possible values are:
- | less than 0: unbounded (default)
- | equal to 0: no queue at all
- | greater than 0: size of the queue
- | max-pool-size: optional maximum number of threads in the pool.
- | Defaults to 5.
- | NOTE: if a queue is specified (queue-sie != 0)
- | this value will be ignored.
- | min-pool-size: optional minimum number of threads in the pool.
- | Defaults to 5.
- | NOTE: if a queue has been specified (queue-sie != 0)
- | this value will be used as the maximum of
- | thread running concurrently.
- | keep-alive-time-ms: The time in ms an idle thread should keep alive
- | before it might get garbage collected. This
- | defaults to 60000 ms.
- | block-policy; The policy to be used if all resources (thread in
- | the pool and slots in the queue) are exhausted.
- | Possible values are:
- | ABORT: Throw a RuntimeException
- | DISCARD: Throw away the current request
- | and return.
- | DISCARDOLDEST: Throw away the oldest request
- | and return.
- | RUN (default): The thread making the execute
- | request runs the task itself.
- | This policy helps guard against
- | lockup.
- | WAIT: Wait until a thread becomes
- | available. This policy should, in
- | general, not be used if the
- | minimum number of threads is zero,
- | in which case a thread may never
- | become available.
- | shutdown-graceful: Terminate thread pool after processing all
- | Runnables currently in queue. Any Runnable entered
- | after this point will be discarded. A shut down
- | pool cannot be restarted. This also means that a
- | pool will need keep-alive-time-ms to terminate.
- | The default value not to shutdown graceful.
- | shutdown-wait-time-ms: The time in ms to wait before issuing an
- | immediate shutdown after a graceful shutdown
- | has been requested.
- +-->
- <property name="threadFactory" value="org.apache.cocoon.components.thread.DefaultThreadFactory"/>
- <property name="threadPools">
- <list>
- <!--+
- | This is the default thread pool. It's use fits best for short
- | running background tasks.
- +-->
- <map>
- <entry key="name" value="default"/>
- <entry key="priority" value="NORM"/>
- <entry key="daemon" value="false"/>
- <entry key="queue-size" value="-1"/>
- <entry key="max-pool-size" value="5"/>
- <entry key="min-pool-size" value="5"/>
- <entry key="keep-alive-time-ms" value="60000"/>
- <entry key="block-policy" value="ABORT"/>
- <entry key="shutdown-graceful" value="false"/>
- <entry key="shutdown-wait-time-ms" value="-1"/>
- </map>
- <!--+
- | This thread pool should be used for daemons (permanently running
- | threads).
- +-->
- <map>
- <entry key="name" value="daemon"/>
- <entry key="priority" value="NORM"/>
- <entry key="daemon" value="true"/>
- <entry key="queue-size" value="0"/>
- <entry key="max-pool-size" value="-1"/>
- <entry key="min-pool-size" value="1"/>
- <entry key="keep-alive-time-ms" value="60000"/>
- <entry key="block-policy" value="ABORT"/>
- <entry key="shutdown-graceful" value="false"/>
- <entry key="shutdown-wait-time-ms" value="-1"/>
- </map>
- </list>
+ | threadPools: container element for thread-pool elements.
+ +-->
+ <property name="workerThreadPools">
+ <configurator:bean-map type="org.apache.cocoon.components.thread.ThreadPool" strip-prefix="true"/>
</property>
</bean>
+
+ <!--+
+ | This is the default thread pool. It's use fits best for short
+ | running background tasks.
+ +-->
+ <bean name="org.apache.cocoon.components.thread.ThreadPool/default" class="org.apache.cocoon.components.thread.DefaultThreadPool" scope="singleton">
+ <!--+
+ | More indepth information can be found at
+ | http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/PooledExecutor.html
+ | The following elements can be used:
+ +-->
+ <!-- required name of the pool -->
+ <property name="name" value="default" />
+ <!--+
+ | optional priority all threads of the pool will have (the ThreadFactory will be
+ | set to this priority).The possible values are:
+ | MIN: corresponds to Thread#MIN_PRIORITY
+ | NORM: corresponds to Thread#NORM_PRIORITY (default)
+ | MAX: corresponds to Thread#MAX_PRIORITY
+ +-->
+ <property name="poolPriority" value="NORM" />
+ <!--+
+ | whether newly created Threads should run in daemon mode or not. Default to false.
+ +-->
+ <property name="daemon" value="false" />
+ <!--
+ | optional size of a queue to hold Runnables if the pool is full. Possible values are:
+ | less than 0: unbounded (default)
+ | equal to 0: no queue at all
+ | greater than 0: size of the queue
+ -->
+ <property name="queueSize" value="-1" />
+ <!--+
+ | optional maximum number of threads in the pool. Defaults to 5.
+ | NOTE: if a queue is specified (queue-sie != 0)
+ | this value will be ignored.
+ +-->
+ <property name="maxPoolSize" value="5" />
+ <!--+
+ | optional minimum number of threads in the pool. Defaults to 5.
+ | NOTE: if a queue has been specified (queue-sie != 0)
+ | this value will be used as the maximum of thread running concurrently.
+ +-->
+ <property name="minPoolSize" value="5" />
+ <!--+
+ | The time in ms an idle thread should keep alive before it might get garbage collected.
+ | This defaults to 60000 ms.
+ +-->
+ <property name="keepAliveTime" value="60000" />
+ <!--+
+ | The policy to be used if all resources (thread in the pool and
+ | slots in the queue) are exhausted.
+ | Possible values are:
+ | ABORT: Throw a RuntimeException
+ | DISCARD: Throw away the current request and return.
+ | DISCARDOLDEST: Throw away the oldest request and return.
+ | RUN (default): The thread making the execute request runs the task itself.
+ | This policy helps guard against lockup.
+ | WAIT: Wait until a thread becomes available. This policy should, in
+ | general, not be used if the minimum number of threads is zero,
+ | in which case a thread may never become available.
+ +-->
+ <property name="blockPolicy" value="ABORT" />
+ <!--+
+ | Terminate thread pool after processing all Runnables currently in queue. Any
+ | Runnable entered after this point will be discarded. A shut down pool cannot
+ | be restarted. This also means that a pool will need keep-alive-time-ms to
+ | terminate. The default value not to shutdown graceful.
+ +-->
+ <property name="shutdownGraceful" value="false" />
+ <!--+
+ | The time in ms to wait before issuing an immediate shutdown after a graceful shutdown
+ | has been requested.
+ +-->
+ <property name="shutdownWaitTimeMs" value="-1" />
+ <!--+
+ | specifies the fully qualified class name of an org.apache.cocoon.components.thread.ThreadFactory
+ | implementation. It is responsible to create Thread classes.
+ +-->
+ <property name="factory" ref="defaultThreadFactory"/>
+ </bean>
+
+ <!--+
+ | This thread pool should be used for daemons (permanently running
+ | threads).
+ +-->
+ <bean name="org.apache.cocoon.components.thread.ThreadPool/daemon" class="org.apache.cocoon.components.thread.DefaultThreadPool" scope="singleton">
+ <property name="name" value="daemon"/>
+ <property name="poolPriority" value="NORM"/>
+ <property name="daemon" value="true"/>
+ <property name="queueSize" value="0"/>
+ <property name="maxPoolSize" value="-1"/>
+ <property name="minPoolSize" value="1"/>
+ <property name="keepAliveTime" value="60000"/>
+ <property name="blockPolicy" value="ABORT"/>
+ <property name="shutdownGraceful" value="false"/>
+ <property name="shutdownWaitTimeMs" value="-1"/>
+ <property name="factory" ref="defaultThreadFactory"/>
+ </bean>
+
+ <bean id="defaultThreadFactory" class="org.apache.cocoon.components.thread.DefaultThreadFactory" scope="prototype" />
</beans>
Modified: cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/test/java/org/apache/cocoon/components/thread/DefaultThreadPoolTestCase.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/test/java/org/apache/cocoon/components/thread/DefaultThreadPoolTestCase.java?view=diff&rev=522946&r1=522945&r2=522946
==============================================================================
--- cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/test/java/org/apache/cocoon/components/thread/DefaultThreadPoolTestCase.java (original)
+++ cocoon/trunk/core/cocoon-thread/cocoon-thread-impl/src/test/java/org/apache/cocoon/components/thread/DefaultThreadPoolTestCase.java Tue Mar 27 08:10:39 2007
@@ -22,122 +22,120 @@
/**
* The $classType$ class ...
- *
- * @version $Id$
+ *
+ * @version $Id: DefaultThreadPoolTestCase.java 494399 2007-01-09 13:10:08Z
+ * cziegeler $
*/
-public class DefaultThreadPoolTestCase
- extends AbstractTestCase {
-
- //~ Methods ----------------------------------------------------------------
+public class DefaultThreadPoolTestCase extends AbstractTestCase {
/**
- * DOCUMENT ME!
- */
- public final void testDefaultThreadPool( )
- {
- final DefaultThreadPool pool = new DefaultThreadPool( );
- pool.setName( "mypool" );
-
- // We cannot mock the DefaultThreadFactory as the underlying
- // PooledExecutor of the DefaultThreadPool will again wrapp it into a
- // PooledExecutor.Worker instance that does some bookeeping.
- // Using a easymocked DefaultThreadFactory will prevent the
- // PooledExecutor from shutting down and thus hangs forever.
- final ThreadFactory threadFactory = new DefaultThreadFactory();
- threadFactory.setPriority( Thread.MAX_PRIORITY );
- pool.setThreadFactory( threadFactory );
- pool.setQueue( 230 );
- pool.setMaximumPoolSize( 15 );
- pool.setMinimumPoolSize( 9 );
- pool.setKeepAliveTime( 11000 );
- pool.setBlockPolicy( "ABORT" );
- pool.setShutdownGraceful( false );
- pool.setShutdownWaitTimeMs( 12345 );
-
- assertEquals( "block-policy", "ABORT", pool.getBlockPolicy( ) );
- assertEquals( "keep-alive-time-ms", 11000L, pool.getKeepAliveTime( ) );
- assertEquals( "max-queueu-size", 230, pool.getMaximumQueueSize( ) );
- assertEquals( "max-pool-size", 15, pool.getMaximumPoolSize( ) );
- assertEquals( "min-pool-size", 9, pool.getMinimumPoolSize( ) );
- assertEquals( "name", "mypool", pool.getName( ) );
- assertEquals( "priority", Thread.MAX_PRIORITY, pool.getPriority( ) );
- assertEquals( "queue-size", 0, pool.getQueueSize( ) );
- assertEquals( "isQueued", true, pool.isQueued( ) );
- assertEquals( "isTerminatedAfterShutdown", false,
- pool.isTerminatedAfterShutdown( ) );
- verify( );
+ * DOCUMENT ME!
+ */
+ public final void testDefaultThreadPool() {
+ final DefaultThreadPool pool = new DefaultThreadPool();
+ pool.setName("mypool");
+
+ // We cannot mock the DefaultThreadFactory as the underlying
+ // PooledExecutor of the DefaultThreadPool will again wrapp it into a
+ // PooledExecutor.Worker instance that does some bookeeping.
+ // Using a easymocked DefaultThreadFactory will prevent the
+ // PooledExecutor from shutting down and thus hangs forever.
+ final ThreadFactory threadFactory = new DefaultThreadFactory();
+ pool.setThreadFactory(threadFactory);
+ pool.setPriority(Thread.MAX_PRIORITY);
+ pool.setQueueSize(230);
+ pool.setMaxPoolSize(15);
+ pool.setMinPoolSize(9);
+ pool.setKeepAliveTime(11000L);
+ pool.setBlockPolicy("ABORT");
+ pool.setShutdownGraceful(false);
+ pool.setShutdownWaitTimeMs(12345);
+ pool.afterPropertiesSet();
+
+ assertEquals("block-policy", "ABORT", pool.getBlockPolicy());
+ assertEquals("keep-alive-time-ms", 11000L, pool.getKeepAliveTime());
+ assertEquals("max-queueu-size", 230, pool.getMaxQueueSize());
+ assertEquals("max-pool-size", 15, pool.getMaxPoolSize());
+ assertEquals("min-pool-size", 9, pool.getMinPoolSize());
+ assertEquals("name", "mypool", pool.getName());
+ assertEquals("priority", Thread.MAX_PRIORITY, pool.getPriority());
+ assertEquals("queue-size", 0, pool.getQueueSize());
+ assertEquals("isQueued", true, pool.isQueued());
+ assertEquals("isTerminatedAfterShutdown", false, pool
+ .isTerminatedAfterShutdown());
+ verify();
}
/*
- * Class under test for void execute(Runnable)
- */
- public final void testExecuteRunnable( )
- throws InterruptedException
- {
- final MockControl runnableControl =
- createStrictControl( Runnable.class );
- final Runnable runnable = (Runnable)runnableControl.getMock( );
- runnable.run( );
- runnableControl.replay( );
-
- final DefaultThreadPool pool = new DefaultThreadPool( );
- pool.setName( "mypool" );
- // We cannot mock the DefaultThreadFactory as the underlying
- // PooledExecutor of the DefaultThreadPool will again wrapp it into a
- // PooledExecutor.Worker instance that does some bookeeping.
- // Using a easymocked DefaultThreadFactory will prevent the
- // PooledExecutor from shutting down and thus hangs forever.
- pool.setThreadFactory( new DefaultThreadFactory() );
- pool.setQueue( 230 );
- pool.setMaximumPoolSize( 15 );
- pool.setMinimumPoolSize( 9 );
- pool.setKeepAliveTime( 100 );
- pool.setBlockPolicy( "ABORT" );
- pool.setShutdownGraceful( false );
- pool.setShutdownWaitTimeMs( 1234 );
- pool.execute( runnable );
- Thread.yield( );
- Thread.sleep( 100 );
- pool.shutdown();
- verify( );
+ * Class under test for void execute(Runnable)
+ */
+ public final void testExecuteRunnable() throws InterruptedException {
+ final MockControl runnableControl = createStrictControl(Runnable.class);
+ final Runnable runnable = (Runnable) runnableControl.getMock();
+ runnable.run();
+ runnableControl.replay();
+
+ final DefaultThreadPool pool = new DefaultThreadPool();
+ pool.setName("mypool");
+ // We cannot mock the DefaultThreadFactory as the underlying
+ // PooledExecutor of the DefaultThreadPool will again wrapp it into a
+ // PooledExecutor.Worker instance that does some bookeeping.
+ // Using a easymocked DefaultThreadFactory will prevent the
+ // PooledExecutor from shutting down and thus hangs forever.
+ pool.setThreadFactory(new DefaultThreadFactory());
+ pool.setQueueSize(230);
+ pool.setMaxPoolSize(15);
+ pool.setMinPoolSize(9);
+ pool.setKeepAliveTime(100);
+ pool.setBlockPolicy("ABORT");
+ pool.setShutdownGraceful(false);
+ pool.setShutdownWaitTimeMs(1234);
+ pool.afterPropertiesSet();
+ pool.execute(runnable);
+ Thread.yield();
+ Thread.sleep(100);
+ pool.shutdown();
+ verify();
}
/**
- * DOCUMENT ME!
- *
- * @throws InterruptedException DOCUMENT ME!
- */
- public final void testShutdown( )
- throws InterruptedException {
- final Runnable runnable = new Runnable(){
- public void run() {
- final Log logger = LogFactory.getLog(DefaultThreadPoolTestCase.this.getClass());
- logger.info( "runnable runs" );
- try {
- Thread.sleep( 1000 );
- } catch( final InterruptedException ie ) {
- logger.info( "runnable has been interrupted ");
- }
- logger.info( "runnable terminated" );
- }
- };
-
- final DefaultThreadPool pool = new DefaultThreadPool( );
- pool.setName( "mypool" );
- pool.setThreadFactory( new DefaultThreadFactory() );
- pool.setQueue( 0 );
- pool.setMaximumPoolSize( 15 );
- pool.setMinimumPoolSize( 9 );
- pool.setKeepAliveTime( 1000 );
- pool.setBlockPolicy( "ABORT" );
- pool.setShutdownGraceful( true );
- pool.setShutdownWaitTimeMs( 100 );
- pool.execute( runnable );
- pool.execute( runnable );
- Thread.yield();
- Thread.sleep( 200 );
- pool.shutdown( );
- Thread.sleep( 200 );
- verify();
+ * DOCUMENT ME!
+ *
+ * @throws InterruptedException
+ * DOCUMENT ME!
+ */
+ public final void testShutdown() throws InterruptedException {
+ final Runnable runnable = new Runnable() {
+ public void run() {
+ final Log logger = LogFactory
+ .getLog(DefaultThreadPoolTestCase.this.getClass());
+ logger.info("runnable runs");
+ try {
+ Thread.sleep(1000);
+ } catch (final InterruptedException ie) {
+ logger.info("runnable has been interrupted ");
+ }
+ logger.info("runnable terminated");
+ }
+ };
+
+ final DefaultThreadPool pool = new DefaultThreadPool();
+ pool.setName("mypool");
+ pool.setThreadFactory(new DefaultThreadFactory());
+ pool.setQueueSize(0);
+ pool.setMaxPoolSize(15);
+ pool.setMinPoolSize(9);
+ pool.setKeepAliveTime(1000);
+ pool.setBlockPolicy("ABORT");
+ pool.setShutdownGraceful(true);
+ pool.setShutdownWaitTimeMs(100);
+ pool.afterPropertiesSet();
+ pool.execute(runnable);
+ pool.execute(runnable);
+ Thread.yield();
+ Thread.sleep(200);
+ pool.shutdown();
+ Thread.sleep(200);
+ verify();
}
}