Spring调度程序错误地递增值
我使用的是spring调度程序。我每5秒调用一次m1()。为什么变量计数的值会随着每次调用而递增? 我希望对m1()的每次调用都独立于前一次调用,所以在对m1的每次调用中,我应该得到count的值为1 如何在每次调用中获得count=1的值Spring调度程序错误地递增值,spring,spring-boot,Spring,Spring Boot,我使用的是spring调度程序。我每5秒调用一次m1()。为什么变量计数的值会随着每次调用而递增? 我希望对m1()的每次调用都独立于前一次调用,所以在对m1的每次调用中,我应该得到count的值为1 如何在每次调用中获得count=1的值 @Component @EnableScheduling public class MySchedulers { @Autowired private DaoService daoService;
@Component
@EnableScheduling
public class MySchedulers {
@Autowired
private DaoService daoService;
@Scheduled(cron = "*/5 * * * * ?")
public void process() {
daoService.serviceMethod();
}
@Repository
public class DbDao {
private int count = 0;
@Value("${test}")
private String str;
public void m1() {
System.out.println(" in dao layer --" + ++count);
}
这是我收到的订单
in dao layer --0
in dao layer --1
in dao layer --2
in dao layer --3
in dao layer --4
为什么变量计数的值会随着每次调用而递增
我相信它会增加,因为DbDao
被定义为singleton,这意味着spring在应用程序上下文中维护一个DbDao
类型的对象,并且这个对象被注入(自动连接)到myscheduler中
在DbDao
的m1
方法中,您总是增加count
数据字段(++count
),因此每次调用时它都会增加,这是预期的行为
如何在每次调用中获得count=1的值
@Component
@EnableScheduling
public class MySchedulers {
@Autowired
private DaoService daoService;
@Scheduled(cron = "*/5 * * * * ?")
public void process() {
daoService.serviceMethod();
}
@Repository
public class DbDao {
private int count = 0;
@Value("${test}")
private String str;
public void m1() {
System.out.println(" in dao layer --" + ++count);
}
这取决于你真正想做什么。例如,不要使用count
作为数据字段,但它实际上取决于场景背后的逻辑
我可以说您可以为DbDao使用prototype作用域,但这并没有真正的意义,因为存储库通常被定义为单例(我不认为有理由在每次调用它时创建一个新的存储库对象)
由于存储库应该从不同的线程同时调用(或者至少支持这种执行模型),所以存储库通常不应该保持状态
更新1
根据OP的评论:
默认情况下使用调度程序时,spring只分配1个线程(池大小=1),因此不会出现任何与线程相关的问题,因为所有调用都将在同一个线程中完成。当然,只要您从“调度器”调用的代码没有被其他流同时调用(比如来自rest控制器、消息侦听器等的流),这是正确的
不过,您可以配置池大小,然后属于调度程序的两个线程可能会调用相同的方法(例如MyDao
中的一个)
在这种情况下,由您决定您到底想要保护什么以及如何保护,spring在这里不会帮助您。正如我在上面所解释的,事实上,由于
MyDao
是一个单例,许多线程将访问它的共享状态,因此在本例中,您可能需要对它做一些事情。SpringBean不是这样工作的,您在单例bean中有一个有状态字段。它每次都以预定的方式调用同一个bean,每次都增加同一个对象中的字段。我如何才能达到我的要求?我的重点是理解每当我在特定的时间间隔后使用Spring scheduler调用某些方法时。我需要ro使其线程安全。对吗?