【问题标题】:Scheduled method in a standalone application in spring春季独立应用程序中的计划方法
【发布时间】:2012-08-24 00:05:15
【问题描述】:

我有一个方法需要在每天 07:00 执行。 为此,我使用该方法创建了一个 bean,并使用 @Scheduled(cron="0 0 7 * * ?") 对其进行了注释。 在这个 bean 中,我创建了一个 main 函数 - 它将初始化 spring 上下文,获取 bean 并调用方法(至少是第一次),如下所示:

public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(args[0]);
    SchedulerService schedulerService = context.getBean(SchedulerService.class);
    schedulerService.myMethod();
}

这很好用 - 但只有一次。 我想我明白为什么 - 这是因为 main 线程结束 - spring 上下文也是如此,所以即使 myMethod@Scheduled 注释它也不会工作。

我想了一个方法来传递这个——意思是不要让main线程死掉,也许是这样的:

while (true){
   Thread.currentThread().sleep(500);
}

这就是我认为应用程序上下文和我的 bean 将保持不变的方式。

我说的对吗?

有没有更好的方法来解决这个问题?

我正在使用 spring 3.1.2。

谢谢。

【问题讨论】:

    标签: java spring scheduled-tasks


    【解决方案1】:

    主线程应该保持活动状态,直到任何非守护线程处于活动状态。如果您的应用程序中有<task:annotation-driven/> 标签,那么 Spring 应该为您启动一个带有一小部分非守护线程池的执行程序,并且主应用程序不应终止。

    您唯一需要做的就是注册一个关闭挂钩以确保在 VM 结束时进行清理。

    context.registerShutdownHook()

    【讨论】:

    • 谢谢!我没有使用 while 循环,它工作得很好!
    【解决方案2】:

    join 方法非常适合:

        try {
            Thread.currentThread().join();
        } catch (InterruptedException e) {
            logger.warn("Interrupted", e);
        }
    

    或者,这是老式的等待方法:

        final Object sync = new Object();
        synchronized (sync) {
            try {
                sync.wait();
            } catch (InterruptedException e) {
                logger.warn("Interrupted", e);
            }
        }
    

    【讨论】:

    • 谢谢,我尝试阅读join() 方法 - 但无法理解 - 这意味着当前线程等待哪个线程完成?
    • 这是连接方法的一个坏例子。假设主线程启动一个子线程来做一些工作。然后主线程结束。在这种情况下,您不希望主线程在另一个线程完成之前完成,就像主线程完成一样,这意味着该进程将完成。因此,主线程可以加入子线程,然后主线程将等待子线程完成。子线程完成后,主线程将恢复,并在加入调用后接机。
    • 谢谢,这意味着主线程将在某个时候完成 - 当它创建的所有线程都完成时。这不是我要找的——我只是不想让主线程结束。
    • 在这种情况下,sync.wait() 对你来说更有意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 2018-09-04
    相关资源
    最近更新 更多