2012-04-24 3 views

ответ

4

Set «истина» на демона собственности для планировщика - например

<!-- task scheduling for @Scheduled annotation --> 
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/> 
<task:executor id="myExecutor" pool-size="1" /> 

<bean id="myScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler"> 
    <property name="poolSize" value="2" /> 
    <property name="threadNamePrefix" value="myScheduler-"/> 
    <property name="waitForTasksToCompleteOnShutdown" value="false" /> 
    <property name="daemon" value="true" /> 
</bean> 
+0

спасибо. это также решение, предложенное в оригинальном билете. – Marcel

0

Вы пробовали иметь свой @Scheduled боб реализовать DisposableBean (так что он может быть информированным, когда контекст Spring завершает работу) и явно закрывая контекст ваш метод main()?

Понятно, что я не вижу, как код может работать так, как вы ожидаете. Spring нужно запускать новые потоки для запуска вашей задачи @Scheduled в момент времени/скорости, которую вы настраиваете, а это значит, что когда код в вашем методе main() завершается, в JVM все еще запущены потоки без демона. Если вы не сообщите Spring, чтобы закрыть эти потоки, тогда как они будут прекращены?

Редактировать: чтобы быть ясным, я думаю, что решение состоит в том, чтобы явно позвонить close() на ваш ApplicationContext. В противном случае Spring не может сказать, что служба-исполнитель запускает запланированные задачи, чтобы закрыть себя. Ключ отключения JVM не будет вызываться, когда main() завершает работу, так как потоки не-daemon все еще запущены.

+0

спасибо за ваш комментарий. реализация «DisposableBean» не решает проблему - поскольку этот код никогда не будет выполнен (задачи просто продолжают работать). в соответствии с весенним документом должно быть достаточно для регистрации крюка выключения, а не для вызова ctx.close() явно. http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/htmlsingle/#beans-factory-shutdown – Marcel

+0

В вашем случае никогда не будет запущен крюк остановки, хотя, поскольку поток, выполняющий факс @Scheduled, все еще работает. Из JVM-документов для 'Runtime.getRuntime(). AddShutdownHook()' - «Виртуальная машина Java отключается в ответ на два вида событий: 1) Программа завершается нормально, когда последний поток не-демона завершается или когда вызывается (эквивалентно, метод System.exit) ... ». Вам нужно будет найти способ сообщить Spring о завершении потока, управляющего заданием «Запланировать». –

+0

Я не использовал это в Spring 3.1, но в 3.0 (у которого не было поддержки аннотаций), это похоже на то, что bean-скрипты могут быть настроены путем добавления 'ScheduledAnnotationBeanPostProcessor', который будет регистрировать бранды @Scheduled с помощью команды ScheduledTaskRegistrar '. Этот BeanPostProcessor полагался на получение сообщения 'destroy()' DisposableBean', чтобы иметь возможность завершить работу службы-исполнителя, чтобы прекратить обработку будущих задач @Scheduled. Я предполагаю, что вам нужно сделать то же самое в 3.1 - убедитесь, что вы явно закрываете свой ApplicationContext, чтобы Spring могла завершить работу исполнителя задачи. –

0

Это решение с использованием Java CONFIG

@Bean 
public TaskScheduler daemonTaskScheduler() { 
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); 
    taskScheduler.setDaemon(false); 
    taskScheduler.setThreadNamePrefix("daemon"); 
    taskScheduler.setPoolSize(5); 
    return taskScheduler; 
} 

или если вы хотите, чтобы действительно получить в детали, конфиг класс может быть таким:

@Configuration 
public class SchedulerConfig implements SchedulingConfigurer { 

    @Override 
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 

Одна вещь не поддерживается, хотя она должна быть в состоянии использовать мульти Несколько TaskSchedulers в одном приложении. Я открыл JIRA за это

Смежные вопросы