我對使用Spring的競態條件有點擔心。 我知道所有種類的範圍之間(單,原型,會話等)的差異春季競賽條件單身服務有狀態或無狀態
我也知道:
- 服務已經默認單範圍
- 我不會有隻要我的豆是無狀態的,競賽條件的問題
即使我對這種無狀態的事情並不百分百確定。在討論有狀態時,我的研究來源始終只關注共享實例變量,但競爭條件不僅會在訪問實例變量時出現。 我創建了下面的例子來說明我的問題:
@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));
}
}
你可以假設該服務在休息控制器或類似的東西使用。根據我的理解,當方法存在AppleInCategory被調用時,競爭條件可能會出現問題。例如,thread1具有其插槽並將「false」寫入變量existsAppleInCategory。然後,線程2使用「true」將其槽覆蓋existsAppleInCategory。之後線程1有另一個時隙。 =>線程1現在「做某事」而不是拋出一個RuntimeException。
我的假設是否正確?在這種情況下,我遇到競賽狀況問題嗎? 如果不是爲什麼?你能否推薦任何關於這個主題的資料(網上資源,書籍......)?
預先感謝您!
不,你的理解是錯誤的......沒有共享狀態(假設'AppleRepository'也是一個線程安全的單例)。每個線程都有其自己的堆棧,並且在該堆棧上,其中包含方法內部使用的變量,所以thread1無法從thread2中看到「existsAppleInCategory」,反之亦然。如果'existsAppleInCategory'是一個實例級別的變量,這將是不同的! –
當然你是對的。現在我覺得我是一個初學者:-) – user1713946