Jeune Jeune - 19 days ago 6
Java Question

Spring ThreadPoolTaskExecutor only running one thread

We are using ThreadPoolExecutor in our JMS consumer and injecting it into a DefaultMessageListenerContainer. I expect this to be running concurrent threads for many messages however our logs show that the thread id won't change.Our logging shows that for different processing of messages, the thread id is always the same at 24.

This is the spring configuration in that scenario:

<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer"
p:connectionFactory-ref="cachedConnectionFactory"
p:destination-ref="formsCRRDestination"
p:messageListener-ref="formServicePojo"
p:concurrentConsumers="5"
p:idleTaskExecutionLimit="1"
p:maxConcurrentConsumers="25"
p:taskExecutor-ref="threadPoolExecutor"
destroy-method="doShutdown"
>


<bean id="threadPoolExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >
<property name="corePoolSize" value="1"/>
<property name="maxPoolSize" value="15"/>
<property name="keepAliveSeconds" value="30"/>
</bean>


After not injecting the threadPoolExectuor bean into the DefaultMessageListenerContainer, the messages are now being executed in different threads.

This is the resulting configuration:

<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer"
p:connectionFactory-ref="cachedConnectionFactory"
p:destination-ref="formsCRRDestination"
p:messageListener-ref="formServicePojo"
p:concurrentConsumers="5"
p:idleTaskExecutionLimit="1"
p:maxConcurrentConsumers="25"
destroy-method="doShutdown"
>


I have tried reading the documentation and I don't understand why this is happening. Any explanation?

Answer

After going through the ThreadPoolTaskExecutor code in Spring and reading the Java docs for ThreadPoolTaskExecutor I think this is the answer:

Unbounded queues. Using an unbounded queue (for example a LinkedBlockingQueue without a predefined capacity) will cause new tasks to be queued in cases where all corePoolSize threads are busy. Thus, no more than corePoolSize threads will ever be created. (And the value of the maximumPoolSize therefore doesn't have any effect.)

In our configuration above, we were using the LinkedBlockingQueue by default and our corePoolSize is 1. This is why the maximumPoolSize won't have any effect.

Comments