Announcement Announcement Module
No announcement yet.
Reducing the thread pool for ServiceActivator's taskexecutor Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Reducing the thread pool for ServiceActivator's taskexecutor

    In a simple PoC I've created a jdbc poller which calls NOW() in hsqldb:

    	<int-jdbc:inbound-channel-adapter id="dbPoller" channel="data" query="call NOW()" data-source="dataSource" auto-startup="true">
    		<int:poller fixed-delay="1000" />
    The data is put on a rendezvous queue
    <int:channel id="data">
    		<int:rendezvous-queue />
    Which is consumed by my very stupid service activator which performs a sysout of the input and a Thread.sleep(1000*10) (10 seconds):
    	<int:service-activator id="sysout" input-channel="data">
    		<int:poller fixed-delay="1000" task-executor="taskExecutor" />
    		<bean id="serviceActivator" class="" />
    The backing taskExecutor is set up with core and max pool size of 10:
    	<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    		<property name="corePoolSize" value="10" />
    		<property name="maxPoolSize" value="10" />
    The code runs fine, but I get into trouble when I try to reduce the threadpool's core and max size runtime using jmx. I first set the corePoolSize to 5 then the maxPoolSize to 5 (reverse order causes exception).

    I wait for the currently executing calls to the serviceactivator to finish, but then I see another 10 sysouts. I inspect the poolSize and activeCount using jmx and they are still at 10 and they stay that way no matter how long I wait.

    If I on the other hand increase the core and max pool size to 30, the change is reflected in the activeCount and the poolSize.

    I've tried setting the keepAliveSeconds to 0, but it doesn't change anything.

    Anyone had a similar problem or some input that might help explain this?
    Last edited by magott; May 9th, 2011, 05:04 AM.

  • #2
    Found a way to get the reduced max/core size to work. If, after I've reduced the max/core size, I stop the 'dbPoller' and then start it again, the thread count is reduced to the new mx/core. So it seems like that as long as there is work to be done on the rendezvous queue the threads won't enter the "idle state", which prevents them from being killed off.

    This was definitely not what I expected, but at least I've found a way to get it to work. I'd still appreciate some input as to whether this is working as designed or not.


    • #3
      My hypothesis is that the thread is not considered idle as long as it can consume new tasks from the queue.
      It seems that it is able to go from executing the ServiceActivator's method to a timed wait (parkNanos) on the AbstractQueuedSynchronizer(Rendezvous internal) without being "idle". As long as new tasks are being put in the queue, the thread wakes
      up before the timeout to perform the tasks. When the dbPoller is stopped, no new tasks are submitted and as such the thread will wake up as a result of a timeout. At this stage, the thread is considered "idle" and is purged before a new
      timed wait can occur.

      What still boggles me is how the thread can go from busy processing to a timed_wait without being "idle" in between, which is apparently what happens when the thread goes from the completion of the ServiceActivator's method and the parkNanos on the rendezvous internals.