调整Spring容器的任务支持使用的线程

时间:2010-05-31 21:41:38

标签: spring scheduled-tasks

是否可以调整Spring容器的任务支持使用的线程数?

2 个答案:

答案 0 :(得分:1)

如果你想在运行时调整它,那么我相信你唯一的选择就是以编程方式进行调整。

java.util.concurrent.ExecutorService注入Spring的任务支持,如下所示:

<bean id="executorService" class="java.util.concurrent.Executors"
    factory-method="newFixedThreadPool">
    <constructor-arg value="5" />
</bean>

<task:annotation-driven executor="executorService" />

然后你可以像这样调整ExecutorService使用的线程:

@Inject
ExecutorService executorService;

public void adjustPoolSize() {
    ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
    threadPoolExecutor.setMaximumPoolSize(10);
    threadPoolExecutor.setCorePoolSize(20);
}

我已经用Spring here写了更多关于并发性的文章。

答案 1 :(得分:0)

如果你的意思是任务,就像计划任务一样,那么我不相信,至少不是直接的,因为任务执行通常是同步的 - 也就是说,同一个任务的两次调用是在同一个线程上执行的 - 这个至少对于为每个Timer使用专用线程的JDK Timer类来说是真的 - 所以定时器的多次触发在同一个线程上执行。

如果要对线程池执行任务,最好的办法是将任务与计时器分开,让计时器在线程池上调用您的任务。您可以配置运行任务的线程池,这样您就可以完全控制线程数。

Timer调用的任务看起来像这样

   public class TimerTaskInvoker extends TimerTask
   {
       TaskExecutor  executor;
       Runnable      taskToRun;

       public void run() {
          executor.execute(taskRoRun);
       }
   }

在你的春季配置

<!-- the thread pool for executing tasks -->
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
  <property name="corePoolSize" value="5" />
  <property name="maxPoolSize" value="10" />
  <property name="queueCapacity" value="25" />
</bean>

<!-- invokes your actual task from the timer -->
<bean id="yourTaskInvoker" class="TimerTaskInvoker">
    <property name="executor" value="taskExecutor"/>
    <property name="taskToRun">
       <bean class="YourTaskClass">
          <!-- your task properties etc... -->
       </bean>
    </property>
</bean>

<!-- schedules execution of yourTaskInvoker -->    
<bean id="scheduledTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
    <!-- wait 10 seconds before starting repeated execution -->
    <property name="delay" value="10000" />
    <!-- run every 50 seconds -->
    <property name="period" value="50000" />
    <property name="timerTask" ref="yourTaskInvoker" />
</bean>