Я пытаюсь преобразовать конфигурацию XML для использования инфраструктуры задач Spring в чисто конфигурацию кода. Я могу воспроизвести функциональность, но всякий раз, когда я закрываю войну на сервере Tomcat, планировщик задач живет, он зависает (он не зависает с конфигурацией XML). Я отлаживал проверку экземпляров планировщика и исполнителя, но я не вижу разницы, поэтому я не уверен, что может заставить его повесить.
Вот конфигурация XML, которая работает:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd">
<task:executor id="com.work.gwx.pix.executor"
pool-size="${pix.job.executor.pool.size:1-40}"
queue-capacity="${pix.job.executor.queue.capacity:0}"
rejection-policy="CALLER_RUNS"/>
<task:scheduler id="com.work.gwx.pix.scheduler" pool-size="${pix.job.scheduler.pool.size:4}" />
<task:annotation-driven executor="com.work.gwx.pix.executor" scheduler="com.work.gwx.pix.scheduler" />
<bean id='queueProcessor' class="com.work.gwx.queueing.QueueProcessor" />
</beans>
Вот конфигурация кода:
@EnableAsync
@EnableScheduling
@Configuration
public class TaskConfiguration implements AsyncConfigurer, SchedulingConfigurer {
@Value("${pix.job.executor.max.pool.size:1}")
private int executorMaxPoolSize;
@Value("${pix.job.executor.queue.capacity:0}")
private int executorQueueCapacity;
@Value("${pix.job.scheduler.pool.size:4}")
private int schedulerPoolSize;
@Bean(destroyMethod = "shutdown")
public Executor pixTaskScheduler() {
final ScheduledThreadPoolExecutor ex = new ScheduledThreadPoolExecutor(schedulerPoolSize, new ThreadPoolTaskExecutor());
// ex.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
return ex;
}
@Bean
public Executor pixExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(executorMaxPoolSize);
executor.setQueueCapacity(executorQueueCapacity);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadFactory(new ThreadPoolTaskExecutor());
executor.initialize();
return executor;
}
@Override
public void configureTasks(final ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(pixTaskScheduler());
}
@Override
public Executor getAsyncExecutor() {
return pixExecutor();
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}
Когда я использую setExecuteExistingDelayedTasksAfterShutdownPolicy(false)
в конфигурации кода, он закрывается, но я беспокоюсь, что может иметь неблагоприятные последствия, поскольку это значение true, когда выполняется через конфигурацию XML. Кроме того, я должен отметить, что класс QueueProcessor выполняет работу, которую я хочу, и я не возражаю, если отсроченные исполнения будут отменены - я просто не хочу, чтобы в настоящее время выполнение потоков было отменено.
Это сообщение, которое я получаю, когда оно зависает:
SEVERE: веб-приложение [/pix-queue-processor] похоже начал поток с именем [ThreadPoolTaskExecutor-1], но не смог остановить его. Вероятно, это приведет к утечке памяти.
Любые идеи о том, что может вызвать повешение? Или, используя этот метод с комментариями, позвольте мне сделать то, что я хочу (не будет убивать запущенную задачу, но отменит отложенные задачи)?