【发布时间】:2015-09-25 09:58:02
【问题描述】:
我有点担心使用 Spring 的竞争条件。 我知道各种范围(单例、原型、会话等)之间的区别
我也知道:
- 服务默认具有单例范围
- 只要我的 bean 是无状态的,我就不会有竞争条件问题
尽管我对这个无国籍的事情不是 100% 确定的。在谈论状态时,我的研究来源总是只关注共享实例变量,但竞争条件不仅会在访问实例变量时出现。 我创建了以下示例来说明我的问题:
@Service
public class AppleService {
@Autowired
private AppleRepository appleRepository;
@Override
public void doSomethingWithAppleCategory(String appleCategory) {
boolean existsAppleInCategory = existsAppleInCategory(appleCategory);
if(existsAppleInCategory) {
// do something
}
else {
throw new RuntimeException("There is no apple in the category: " + appleCategory);
}
}
private boolean existsAppleInCategory(String appleCategory) {
Iterable<Apple> allApples = appleRepository.findAll();
return allApples.stream().anyMatch(a -> a.getAppleCategory().equals(appleCategory));
}
}
您可以假设该服务用于休息控制器或类似的东西。据我了解,当调用方法 existsAppleInCategory 时,竞争条件可能会出现问题。例如,thread1 有它的插槽并将“false”写入变量 existsAppleInCategory。然后线程 2 用“true”覆盖它的插槽 existsAppleInCategory。之后线程 1 有另一个时隙。 => 线程 1 现在“做某事”而不是抛出 RuntimeException。
我的假设正确吗?在这种情况下,我是否遇到竞争条件问题? 如果不是为什么?您能否推荐任何有关该主题的详细资料(在线资料、书籍等)?
提前谢谢你!
【问题讨论】:
-
没有。你的理解是错误的......没有共享状态(假设
AppleRepository也是一个线程安全的单例)。每个线程都有自己的堆栈,并且在该堆栈上,除其他外,还有方法内部使用的变量,因此 thread1 无法从 thread2 看到existsAppleInCategory,反之亦然。如果existsAppleInCategory是实例级变量,这将有所不同! -
你当然是对的。现在我觉得我是个初学者:-)
标签: java multithreading spring spring-mvc race-condition