2016-09-26 66 views
0

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

配置

@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 

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

回答

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。

0

尝试改变你的执行人是这样的:

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

我希望这将节省您的时间!

+0

从'newSingleThreadScheduledExecutor'的Executor文档:“与其他等价的'newScheduledThreadPool(1)'不同,保证返回的执行程序不能重新配置为使用其他线程。”所以结果是一样的,除了我目前的代码保证没有额外的线程。在我自己的测试中,我已经尝试过您的示例,以使其发挥作用并获得相同的结果。 – kgengler