多个线程池中的Spring计划任务重叠

时间:2016-09-26 22:01:06

标签: java spring multithreading scheduled-tasks

我有一个每小时运行的Spring计划任务,需要在不重叠的情况下运行。 但是,我遇到了两次启动任务的问题,但是在单独的线程池中。

配置

@Configuration
@EnableScheduling
public class AppConfiguration implements SchedulingConfigurer {

    // ...

    @Bean(destroyMethod="shutdown")
    public Executor taskExecutor() {
        return Executors.newSingleThreadScheduledExecutor();
    }

    @Override
    public void configureTasks(final ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(taskExecutor());
    }
}

职业分类

@Service
public class JobClass {

    @Scheduled(fixedDelay = 3600000)
    public void doJob() {
        LOG.debug("Start Task");
    }
}

日志输出

DEBUG 2016-09-26 15:49:08,874 [pool-2-thread-1][] JobClass - Start Task
DEBUG 2016-09-26 15:49:10,249 [pool-1-thread-1][] JobClass - Start Task

有没有办法强制只使用一个线程池?

2 个答案:

答案 0 :(得分:0)

尝试像这样更改执行者:

@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
    return Executors.newScheduledThreadPool(1);
}

我希望它能节省你的时间!

答案 1 :(得分:0)

所以在第二天回来之后,我能够相对较快地解决这个问题。它最终成为我从另一个应用程序复制/粘贴web xml的问题。

我的网页xml包含以下内容:

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    version="2.5">

    <!-- Dispatcher Servlet -->
    <servlet>
        <servlet-name>dispatcher-servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>com.example.AppConfiguration</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher-servlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <!-- Spring Context Loader -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.example.AppConfiguration</param-value>
    </context-param>

</web-app>

所以发生了什么,是执行程序没有在多个池中创建一个线程。我正在创建两个正在执行计划任务的上下文。我能够通过删除Dispatcher Servlet配置的配置来解决这个问题(我不需要它用于此应用程序)。对于任何可能遇到需要调度程序servlet的同一问题的人来说,应该有两个独立的配置类,一个用于spring上下文,另一个用于servlet。