From version 3.1, ServiceMix now uses separate and configurable thread pools for each component and SEDA queue, which allow much more tuning when needed.
By default, all components and SEDA queues will create its own thread pool through the org.apache.servicemix.executors.ExecutorFactory. Each of these thread pools can be configured using a number of parameters:
Parameter |
Default |
Description |
corePoolSize |
4 |
|
maximumPoolSize |
-1 |
|
keepAliveTime |
60000 |
|
threadDaemon |
false |
|
threadPriority |
Thread.NORM_PRIORITY |
|
queueSize |
1024 |
|
shutdownDelay |
1000 |
|
allowCoreThreadsTimeout |
true |
|
Each thread pool has its own identifier, for example:
- component.id where id is the name of the component
- flow.seda.id where id is the name of the component
- flow.jca.destination where destination is the name of the JMS destination used
Thread pools are configured hierarchically using these ids. It means that when an executor is created with an id of <code>foo.bar</code>, the factory will look for a configuration in the following way:
- configs.get("foo.bar")
- configs.get("foo")
- defaultConfig
Following is an example configuration of the factory:
<sm:container ...>
<sm:executorFactory>
<bean class="org.apache.servicemix.executors.impl.ExecutorFactoryImpl">
<property name="defaultConfig">
<bean class="org.apache.servicemix.executors.impl.ExecutorConfig">
<property name="corePoolSize" value="4"/>
<property name="maximumPoolSize" value="-1"/>
<property name="queueSize" value="0"/>
</bean>
</property>
<property name="configs">
<map>
<entry key="flow.seda">
<bean class="org.apache.servicemix.executors.impl.ExecutorConfig">
<property name="corePoolSize" value="32"/>
<property name="maximumPoolSize" value="-1"/>
<property name="queueSize" value="1024"/>
</bean>
</entry>
</map>
</property>
</bean>
</sm:executorFactory>
...
</sm:container>
Usually, three parameters will be used to configure the behavior of the thread pool:
- corePoolSize
- maximumPoolSize
- queueSize
When the executor receives a new task, the following happen:
- if the number of threads is less than corePoolSize, the executor will create a new thread to handle the job
- if the number of queued jobs is less than queueSize, the job is queued
- is the queue is full and the number of threads is less than maximumPoolSize, a new thread is created to handle the job
- else, the current thread will handle the job
Note that maximumPoolSize and queueSize can be set to -1 to not bound these values.