volatile przy static?

0

Witam

Mam klase "Flagi" w której znajdują się same pola typu public static. Różne wątki korzystają z tych pól i mogą je również zmieniać. Czy jest sens aby wzbogacić takie pole volatile? Wydaje mi się, ze nie bardzo.

Lub inaczej - w klasie dziedziczącej po Thread mam pole public static i wg mnie takie pole powinno być volatile (przy czym w tej klasie zmianę pola może wykonać tylko wątek tej klasy lub wątek główny).

0
lipkerson napisał(a)

Mam klase "Flagi" w której znajdują się same pola typu public static. Różne wątki korzystają z tych pól i mogą je również zmieniać.

To ryzykowne i odradzają tego autorzy wszystkich książek o współbieżności w Javie jakie znam. No chyba, że te pola są z rodziny klas Atomic. Dla pól innego typu istnieją krótkie, celowo spreparowane przykłady w Javie, które udowadniają, że taka konstrukcja spowoduje awarię danych.

Czy jest sens aby wzbogacić takie pole volatile? Wydaje mi się, ze nie bardzo.

Volatile powoduje, że pomijane będą optymalizacje odczytu (rejestry CPU, inne stosy wątków) oraz cache. Jest sens używać tego głównie wtedy kiedy pole może zostać zmodyfikowane przez kod/sprzęt spoza JVM lub kiedy pole jest używane między wątkami bez osobnej synchronizacji między wątkami (a taki przypadek właśnie tutaj zachodzi). Modyfikatora tego można używać właściwie tylko od wersji 1.5 Javy bo wcześniej był źle zaimplementowany.

Lub inaczej - w klasie dziedziczącej po Thread mam pole public static i wg mnie takie pole powinno być volatile (przy czym w tej klasie zmianę pola może wykonać tylko wątek tej klasy lub wątek główny).

Powinno. A poza tym czy ta klasa jest singletonem?

Moim zdaniem aby udostępniać między wątkami jakąkolwiek zmienną niesynchronizowaną, to zmienna ta powinna być volatile oraz klasy np. AtomicInteger. W innym wypadku łamie się odkryte już reguły współbieżności.

0

Nawet jeżeli w tej klasie są same flagi typu boolean ? Czym może się taka flaga rozjechać, ze lepiej jest stosować AtomicBoolean?

0

Rozjechac sie nie moze poniewaz masz gwarancje w spec JVM ze przypisywanie pol (poza long na 32bit VM) oraz referencji jest atomowe. W AtomicBoolean masz np getAndSet, compareAndSet, ktore sa atomowe - nie musisz uzywac jawnej synchronizacji, te metody maja wewnatrz sprytnego busy-waita ktory zapewnia spojnosc.
Co do uzywania AtomicXXX, to wcale nie jest tak ze one sa zawsze lepsze. Wrecz przeciwnie, czytalelm jakis artykil ktory udowadnial ze czesto jest wrecz przeciwnie, poniewaz tam sa busy-waity ktore moga miec duzy ujemny wplyw.

0

Akurat boolean ma rzekomą gwarancję niepodzielności (ale nie wiem czy dotyczy to wyłącznie JVM Suna czy standardu języka) bo jedyne operacje na tym typie to zapis i odczyt. Mimo to volatile i tak jest potrzebne aby zmiana ustawiona przez jeden wątek była natychmiast widoczna również z innych wątków. Wątpię też aby klasa AtomicBoolean została stworzona wyłącznie dla sztuki. Przecież programy Javy mogą być odpalane na różnych maszynach i różnych JVM. Na pewno zarówno synchronizacja jak i obiekty klas Atomic są wolniejsze od bezpośredniego użycia zmiennej volatile boolean w różnych wątkach, na pewno jednak bardziej bezpieczne od uszkodzenia danych lub deadlocka.

1 użytkowników online, w tym zalogowanych: 0, gości: 1