Wpis z mikrobloga

Czy to, że zapis do double lub long jest nieatomowy ma jakiekolwiek znaczenie skoro i tak jeśli taka zmienna jest zmienna i współdzielona to trzeba ją zsynchronizować czy tam zvolatilalizować?
Jakiś przykład?

no chyba, że final double x = 2.0; przy odczycie może dawać różne wyniki? no chyba nie...

A inicjacja obiektów, które mają atrybuty np. int te nie jest atomowe se, jeśli atrybuty nie sá final?

https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html

#java #programowanie
  • 14
  • Odpowiedz
@awiner:

tak jak napisałem se:

jeśli taka zmienna jest zmienna i współdzielona to trzeba ją zsynchronizować czy tam zvolatilalizować?


i jakby to był int to sytuacja by wyglądała tak samo se
  • Odpowiedz
@aczutuse: Równoległe modyfikowanie niewolatylnego pola bez synchronizacji to przepis na niezły burdel. Tego nie powinno się robić niezależnie od typu tego pola.
Jeśli chodzi o pola finalne, to po ich zainicjalizowaniu wszystko będzie ok. Czytanie pól finalnych przed zainicjalizowaniem to kolejny przepis na burdel.
Obczaj klasę AtomicLong i pokrewne.
  • Odpowiedz
Czy to, że zapis do double lub long jest nieatomowy ma jakiekolwiek znaczenie skoro i tak jeśli taka zmienna jest zmienna i współdzielona to trzeba ją zsynchronizować czy tam zvolatilalizować?


@aczutuse: Właśnie między innymi dlatego trzeba używać synchronized albo volatile. To jest jeden z przypadków kiedy niepoprawnie napisany program może się skaszanić w spektakularny sposób. Zwróć uwagę że nie dość że możesz otrzymać nieaktualną wartość to co więcej możesz uzyskać
  • Odpowiedz
@Waffenek: no, ale przy int też muszę używac synchronized czy volatile mimo że zapis jest atomowy, bo może nie przejść ten zapis przez memory barrier se, więc po co mi ta wiedza w praktyce o nieatomowości zapisu long?
  • Odpowiedz
dość że możesz otrzymać nieaktualną wartość to co więcej możesz uzyskać liczbę która nigdy nie została tam zapisana(bo odczytasz częściowo zaktualizowaną wartość)


@aczutuse: Jak napisałem wyżej, w przypadku inta dostaniesz nieaktualną wartość, w przypadku longa możesz dostać część bitów ze starszej wartości i część z nowszej - czyli coś co nigdy nie zostało zapisane.
  • Odpowiedz
@63274682374: Aby tego uniknąć, ogólnie wystarczy przepuścić kod przez jakiś linter (np. ten wbudowany w IntelliJ), który wyłapie najczęstsze sytuacje, gdy pole finalne jest odczytywane przed inicjalizacją:
– wywołania metod w konstruktorze, zwłaszcza jeśli są to metody nieprywatne niefinalne, bo nie kontrolujesz ich nadpisań
– dla pól statycznych, cykliczne zależności między klasami
Weź np. taki kod: class A { final int x; A(){ foo(); x = 1; } void foo()
  • Odpowiedz