Jest bardzo dobrze znane wśród programistów Java, że aby podwójne sprawdzanie blokowania działało poprawnie, zmienna musi być zadeklarowana jako volatile
, a synchronizacja inicjowania obiektu nie jest wystarczająca.Czy "volatile" jest wymagane do podwójnego sprawdzenia blokowania w Javie, ale nie C#?
Świadomość jest prawdopodobnie spowodowana tym, że semantyka słowa kluczowego volatile
została zmieniona w 1.5, tak aby zawierała relację "dzieje się wcześniej", przynajmniej częściowo w celu zapewnienia bezpiecznego podwójnego sprawdzenia; z tego, co rozumiem, relacja "dzieje się przed" oznacza, że zapis do zmiennej lotnej powoduje zapisanie wszystkich zapisanych w pamięci podręcznej zmiennych w wątku do pamięci głównej, a po odczytaniu ze zmiennej lotnej wszystkie zmienne buforowane są uważane za nieaktualne i muszą być ponownie odczytać z pamięci głównej, aby wszystko zapisane przed zapisaniem do zmiennej ulotnej miało "zdarzyć się przed" późniejszym odczytem z tej zmiennej.
przepełnienie stosu seems to believe że dla C# volatile
jest konieczne dla Blokada z podwójnym zatwierdzeniem (mimo zauważyć obawy, że może to być specyficzne dla niektórych procesorów lub do wdrożenia Microsoft), jednocześnie wierząc, że semantyka synchronized
oświadczenia Java są exactly the same jak C# 's oświadczenie lock
, co sugeruje, że te same problemy zidentyfikowane w Javie również istniałyby dla C#, chyba że istnieje jakaś inna zasadnicza różnica w semantyce podwójnie sprawdzanego blokowania między dwoma językami.
Więc ... co jest poprawne? Czy podwójnie sprawdzane blokowanie w C# jest mniej niebezpieczne niż w Javie? Jeśli tak, to jakie semantyki różnią się w tym przypadku?
Jeśli nie, to co konkretnie może pójść źle bez volatile
? Czy semantyka z volatile
w języku C# ustanawia relację "dzieje się przed" jak Java, tak, że podwójne sprawdzanie blokowania jest tak samo bezpieczne w języku C# z volatile
jak w Javie od 1.5?
Zobacz [to (http://blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three.aspx) i [ to] (http://stackoverflow.com/a/5821201/116614). – mellamokb