春季任务:调度程序XML配置问题

时间:2019-01-27 15:29:30

标签: java spring scheduling

我在Bean中有一些函数,我想每5秒运行一次,该变量应“通用化”而不是硬编码:

工作代码如下:(我已经用相关的XML编写了

@Component
@EnableScheduling
public class CacheManager{


    @Scheduled(initialDelay=0,fixedDelay=5000)  
    public void updateConfigurations() {

        Some Code Here
    }

    @Scheduled(initialDelay=0,fixedDelay=5000)
    public void updateMapping() {

        Some Code Here

    }

}

这两个函数每5秒执行一次。

现在,当我要将其移动到XML中时:

<task:scheduler id="ttScheduler" pool-size="1" />

    <task:scheduled-tasks scheduler="ttScheduler">
        <task:scheduled ref="cacheManager" method="updateConfigurations" fixed-delay="5000" initial-delay="0" />
        <task:scheduled ref="cacheManager" method="updateMapping" fixed-delay="5000" initial-delay="0" />
    </task:scheduled-tasks>


@Component
public class CacheManager{


    public void updateConfigurations() {

        log.info("update configurations");

        Some Code

        log.info("end update configurations");
    }

    public void updateMapping() {

        Some Code Here

    }

}

两个函数均无延迟执行。 输出:

20190127-17:24:48.254  INFO [ttScheduler-1] CacheManager[109] - end update  configurations
20190127-17:24:48.255  INFO [ttScheduler-1] CacheManager[105] - update  configurations
20190127-17:24:48.282  INFO [ttScheduler-1] CacheManager[109] - end update  configurations
20190127-17:24:48.283  INFO [ttScheduler-1] CacheManager[105] - update  configurations
20190127-17:24:48.311  INFO [ttScheduler-1] CacheManager[109] - end update  configurations
20190127-17:24:48.312  INFO [ttScheduler-1] CacheManager[105] - update  configurations
20190127-17:24:48.337  INFO [ttScheduler-1] CacheManager[109] - end update  configurations
20190127-17:24:48.337  INFO [ttScheduler-1] CacheManager[105] - update  configurations
20190127-17:24:48.362  INFO [ttScheduler-1] CacheManager[109] - end update  configuration
...
...

更新:我已经将错别字:固定为固定延迟(生成相同的输出) 该应用程序是在tomcat 8下运行的Web应用程序。

根据Dmitry Khamitov的建议,我制作了小应用程序(这次不是Web)。它确实可以作为单个可执行应用程序运行,但是仍然与我编写相同的代码一样,但是在Web应用程序环境下无法运行。

工作测试代码示例:

public class SpringTestApplication {

    private final AtomicInteger counter = new AtomicInteger();

    public void updateConfigurations() throws InterruptedException {

        if (counter.getAndIncrement() == 0) {

            Date instant = new Date(System.currentTimeMillis());
            SimpleDateFormat sdf = new SimpleDateFormat( "HH:mm:ss" );
            String time = sdf.format( instant );
            System.out.println( "Time: " + time );

            Thread.sleep(5000);
        }

        Date instant = new Date(System.currentTimeMillis());
        SimpleDateFormat sdf = new SimpleDateFormat( "HH:mm:ss" );
        String time = sdf.format( instant );
        System.out.println( "Time: " + time );
    }

    public static void main(String[] args) {
        new ClassPathXmlApplicationContext("spring.xml");
    }
}

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/task 
        http://www.springframework.org/schema/task/spring-task-4.2.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <bean id="SpringTestApplication" class="com.example.demo.SpringTestApplication" scope="singleton">

    </bean>

    <task:scheduler id="ttScheduler" pool-size="1"/>
    <task:scheduled-tasks scheduler="ttScheduler">
        <task:scheduled ref="SpringTestApplication" method="updateConfigurations" fixed-delay="5000" initial-delay="0"/>
    </task:scheduled-tasks>



</beans>

1 个答案:

答案 0 :(得分:1)

这可能是因为在XML中使用固定速率,而在Java配置中使用固定延迟。正如Official Spring Doc所述:

  

... 固定延迟,指示每个任务执行完成后要等待的毫秒数。另一个选项是 fixed-rate (固定利率),它指示该方法应多久执行一次,而不管以前执行过多长时间。

因此,如果您的示例中的某些代码在某个时间间隔内花费的时间比固定速率花费的时间长得多,则连续的任务可能只是在该时间间隔内排队了。一旦完成了繁重的执行,并且如果下一次执行恰好是轻量级的,那么您将在日志中看到所看到的内容,直到ScheduledExecutorService的队列耗尽为止。之后,您的轻量级任务将开始以固定速率的毫秒数运行。

尝试在日志中搜索首次执行,以查看它们花费的时间。您也可以注释掉某些代码并重新启动应用程序,以查找根本原因。下面是我的模拟示例,该示例预期每1秒钟运行一次,但其第一次运行需要5秒钟:

public class CacheManager {
    private static final Logger LOG = LoggerFactory.getLogger(CacheManager.class);

    private final AtomicInteger counter = new AtomicInteger();

    public void updateConfigurations() throws InterruptedException {
        LOG.info("update configurations");
        if (counter.getAndIncrement() == 0) {
            Thread.sleep(5000);
        }
        LOG.info("end update configurations");
    }

    public static void main(String[] args) {
        new ClassPathXmlApplicationContext("spring.xml");
    }
}
<beans ...>
    <bean id="cacheManager" class="CacheManager"/>

    <task:scheduler id="ttScheduler" pool-size="1"/>
    <task:scheduled-tasks scheduler="ttScheduler">
        <task:scheduled ref="cacheManager" method="updateConfigurations" fixed-rate="1000" initial-delay="0"/>
    </task:scheduled-tasks>
</beans>

输出:

21:00:58.703 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.706 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:03.706 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:03.707 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.708 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:03.708 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:03.708 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:04.707 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:04.708 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:05.706 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:05.706 [ttScheduler-1] INFO  CacheManager - end update configurations
21:01:06.704 [ttScheduler-1] INFO  CacheManager - update configurations
21:01:06.704 [ttScheduler-1] INFO  CacheManager - end update configurations