我已经创建了一个具有默认(Singleton)范围的类的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实例的访问权限吗?
2 回答
应用程序和调度服务都使用完全相同的实例 . 没有同步,因此调度服务可以在您的应用程序调用它时运行该方法 .
几乎与您在同一时间可由多个线程访问的内容中注入
TaskService
的方式相同,并且这些线程同时调用该方法 .@Scheduled
背后没有黑魔法:它以与手动相同的方式调用您的方法 . 如果该方法不是线程安全的,则需要回退Java中的常规同步机制(例如,通过在方法声明中添加synchronized
关键字) .Spring Singleton,并不代表您对Design Patterns Singleton的期望 . 在Spring中,Singleton意味着bean只创建了一个实例(不意味着另一个实例无法创建),并且只要Spring需要该类型,就会使用该实例 .
在您的情况下,
hourlyReportTask()
方法将执行两次 .