【问题标题】:Spring @Scheduled annotation and Singleton classSpring @Scheduled 注解和 Singleton 类
【发布时间】:2014-08-30 00:15:48
【问题描述】:

我创建了一个具有默认(单例)范围的类的 bean。在课堂上,我有一个计划每小时运行一次的方法。

public class TaskService implements InitializingBean {

    @Scheduled(cron="0 0 */1 * * ?")
    public void hourlyReportTask()
    {
        ... code here ...
    }

    public void performAllTasks()
    {
        hourlyReportTask();
        ...
        ...
    }

}

我的应用程序配置看起来像这样,

<bean id="reportService" 
            class="com.tasks.TaskService" />

我假设运行计划任务的线程将使用相同的 TaskService bean,因为它是在单例范围内创建的。如果应用程序当前正在运行 hourlyReportTask() 并且 Spring 容器启动一个后台调度线程同时运行 hourlyReportTask() 会发生什么。它会等待访问 TaskService 实例吗?

【问题讨论】:

  • 有同步,不用等待。
  • @Sotirios Delimanolis:你的意思是没有同步吗?
  • 是的,打错字了,抱歉。

标签: java spring spring-annotations spring-scheduled


【解决方案1】:

您的应用程序和调度服务都使用完全相同的实例。没有同步,因此调度服务可能会在您的应用程序调用它时运行该方法。

几乎与您将TaskService 注入可以由多个线程同时访问并且这些线程同时调用该方法的东西中的方式相同。

@Scheduled 背后没有黑魔法:它以与手动方式相同的方式调用您的方法。如果该方法不是线程安全的,则需要使用 Java 中的常规同步机制(例如,通过在方法声明中添加 synchronized 关键字)。

【讨论】:

    【解决方案2】:

    Spring Singleton,并不意味着您对 Design Patterns Singleton 的期望。在 Spring 中,Singleton 意味着一个 bean 只创建了一个实例(并不意味着不能创建另一个实例),并且在 Spring 需要该类型时使用该实例。

    在您的情况下,您的 hourlyReportTask() 方法将执行两次。

    【讨论】:

      猜你喜欢
      • 2020-10-02
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-07
      • 1970-01-01
      • 2018-10-31
      • 2013-01-15
      相关资源
      最近更新 更多