Getting Spring scheduled tasks to run with the task executor thread

8.4k views Asked by At

Background: I use Spring 3.0.x in my Websphere 7 applications to grab the CommonJ WorkManager and TimerManager. I use these to do arbitrary tasks at certain intervals in my deployed applications.

Problem:

I just learned that when setting a bean in the scheduler like so:

<bean id="threadTest" class="test.ThreadTester" />

<task:scheduled-tasks scheduler="myTimerExecutor">
    <task:scheduled ref="threadTest" method="execute" fixed-delay="300000" />
</task:scheduled-tasks>

In Websphere, it will run the ThreadTester class directly in the TimerManager thread pool. This thread pool has a much higher priority (and fewer threads) than the WorkManager thread pool. I want the thread to run with the WorkManager instead to be at the proper priority and use the proper resources set up for threads.

As an alternative, instead of setting the bean in the scheduler like above, I can use the Spring @Scheduled annotation in the ThreadTester class like so:

@Scheduled(fixedDelay = 300000)
public void execute() {
    ...
}

Question:

Does using the @Scheduled annotation make the scheduled class run in the TimerManager thread pool or the WorkManager thread pool?

If it runs using the WorkManager, then great! That solves my problem. However, if it is using the TimerManager to directly execute the class, then I guess I'll have to write some wrapper to correctly call the WorkManager.

Thanks for any help!

Edit: Here I include how I set up the scheduler and executor with the Websphere 7 commonj implementations:

<bean id="myTaskExecutor" class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor"> 
    <property name="workManagerName" value="wm/default" />
    <property name="resourceRef" value="true"/>
</bean>

<bean id="myTaskScheduler" class="org.springframework.scheduling.commonj.TimerManagerTaskScheduler"> 
    <property name="timerManagerName" value="tm/default" />
    <property name="resourceRef" value="true" />
    <property name="shared" value="false" />
</bean>

<task:annotation-driven executor="myTaskExecutor" scheduler="myTaskScheduler" /> 
2

There are 2 answers

1
faffy On BEST ANSWER

Well, I found out that yes, indeed, @Scheduled beans are run within the TimerManager thread pool on Websphere 7.

All I had to do was spit out the stack trace of the thread to see the hierarchy in which it was called.

for(StackTraceElement element: Thread.currentThread().getStackTrace()) {
    logger.debug(element.toString());
}
0
Biju Kunjummen On

Looking at the Spring documentation it looks like you will have to use a specific TaskScheduler to run in the TimerManager threadpool - TimerManagerTaskScheduler.

<bean name="scheduler" class="org.springframework.scheduling.commonj.TimerManagerTaskScheduler">
...
</bean>

<task:scheduled-tasks scheduler="scheduler">
    <task:scheduled ref="threadTest" method="execute" fixed-delay="300000" />
</task:scheduled-tasks>