Edit:
Hrm. Kiedy to czytam, jest to technicznie niepoprawne, ale w praktyce z pewnymi zastrzeżeniami. Tylko ostatnie pola można bezpiecznie zainicjować raz i uzyskać dostęp do wielu wątków bez synchronizacji.
Lazy zainicjowane wątki mogą cierpieć z powodu problemów z synchronizacją na wiele sposobów. Na przykład, możesz mieć warunki wyścigu konstruktorów, w których odniesienie do klasy zostało wyeksportowane bez sama klasa jest w pełni zainicjalizowana.
Myślę, że to zależy od tego, czy masz prymitywne pole, czy obiekt. Pierwotne pola, które można zainicjować wiele razy, jeśli nie przeszkadza ci to, że wiele wątków sprawdzi się poprawnie. Jednak inicjalizacja stylu w ten sposób może być problematyczna. Nawet wartości long
na niektórych architekturach mogą przechowywać różne słowa w wielu operacjach, więc można wyeksportować połowę wartości, chociaż podejrzewam, że long
nigdy nie przekroczyłoby strony pamięci, a więc nigdy by się to nie wydarzyło.
myślę, że to zależy w dużym stopniu od tego, czy aplikacja ma żadnych bariera pamięci - wszelkie synchronized
bloki lub dostępu do volatile
dziedzinach. Diabeł tkwi w szczegółach tutaj, a kod, który wykonuje leniwą inicjalizację, może działać dobrze na jednej architekturze z jednym zestawem kodu, a nie w innym modelu gwintu lub z aplikacją, która rzadko synchronizuje.
Oto dobry kawałek na polach końcowych jako porównania:
http://www.javamex.com/tutorials/synchronization_final.shtml
Jako Java 5, jeden szczególności wykorzystanie końcowego słów kluczowych jest bardzo ważny i często pomijany broń w twoja zbrojownia współbieżności. Zasadniczo, ostateczny może być użyty, aby upewnić się, że podczas konstruowania obiektu inny wątek uzyskujący dostęp do tego obiektu nie widzi tego obiektu w stanie częściowo skonstruowanym, jak mogłoby się zdarzyć w innym przypadku.Dzieje się tak dlatego, że w przypadku użycia jako atrybutu zmiennych obiektu, ostateczna ma następującą ważną cechę jako część jego definicji:
Teraz, nawet jeśli pole jest oznaczone jako ostateczne, jeśli jest klasą, może modyfikować pola w klasie. To jest inny problem i nadal musisz mieć synchronizację.
nie obawiaj się lotnych odczytów. Inicjalizacja klasy, tzn. modyfikowalny kod jest jedynym przenośnym sposobem, aby zrobić to bez lotności. Instrukcja jest niepoprawna w obliczu architektury procesora, która umożliwia zmianę kolejności zapisów.Na x86 i Sparc TSO volatile read jest darmowy, więc nie ma sensu grać hakerem. – bestsss