2014-04-15 11 views
5

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?

+0

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

Odpowiedz

2

Od MSDN: "Lotne słowo kluczowe wskazuje, że pole może być modyfikowane przez wiele wątków, które są wykonywane w tym samym czasie. Pola, które są zadeklarowane jako niestabilne, nie podlegają optymalizacji kompilacji, które zakładają dostęp przez pojedynczy wątek. że najbardziej aktualna wartość jest obecna w terenie przez cały czas. "

Tak, lotny jest przydatny tylko wtedy, gdy zmieniasz wartość zmiennej z wielu wątków. Jeśli zablokujesz() obszary kodu, które udostępniają zasoby współdzielone tym samym obiektem blokującym, masz gwarancję, że tylko jeden wątek może uzyskać dostęp do tych obszarów kodu jednocześnie, wówczas zmienna nie jest potrzebna, chyba że modyfikujesz obiekt blokujący (co jest naprawdę złym pomysłem) .

Powiązane problemy