0

我创建了一个具有默认(单例)范围的类的 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 实例吗?

4

2 回答 2

4

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

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

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

于 2014-03-27T09:01:53.983 回答
3

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

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

于 2014-03-26T18:23:01.793 回答