Diskuze: Synchronized vs. Volatile
Zobrazeno 3 zpráv z 3.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
Ahoj, víš, že v Javě moc nedělám, ale zkusím to Problém se synchronizací vláken evidentně chápeš, ale raději ho zopakuji. Představ si 2 metody:
getZustatekUctu()
vyberZUctu(int kolik)
A nyní si představ následující kód:
if (getZustatekUctu() >= 100)
vyberZUctu(100);
Tento kód budeš mít ve vláknu a to spustíš 2x. Problém je v tom, jak OS s vlákny pracuje. Procesor nic jako paralelní běh neumí, ve skutečnosti je to simulované OS a procesor jen mezi vlákny rychle přepíná (uspává je a probouzí), nám se poté zdá, že běží současně. Přepínání provádí OS na základě priorit, vytížení a podobně. Nikdy tedy nevíme, kdy naše vlákno uspí a kdy ho opět probudí.
Představ si, že běží tedy 2 vklákna. Na účtu je 150 Kč. První vlákno provede podmínku, ta platí a poté se OS rozhodne vlákno uspat (to se může jednoduše stát). Nastupuje druhé vlákno, to provede podmínku, ta platí a vybere 100 Kč. Na účtu zbude 50 Kč. Vlákno skončí a probouzí se první vlákno. To pokračuje kde přestalo a vybere 100 Kč. Na účtu je -50 Kč, právě jsme dospěli do nekonzistentního stavu. Přitom jsou podmínky v pořádku.
Problém je samozřejmě v tom, že operace kontroly stavu a výběru neproběhly bezprostředně zasebou. Proto volání metod uzavřeme do bloku synchronized. Hovoříme o zamknutí (Lock), operace se budou provádět bezprostředně po sobě.
Pořadí metod není jediným problémem vláken. Ony jsou vlastně dva, náš program může rozbít ještě cachovaná paměť. Když vlákno běží na jádru procesoru, nemá k dispozici tu samou paměť, jako vlákno v jiném jádru. Používá cachovanou hodnotu. Asi si dokážeš představit, že může dojít k podobnému problému, jako s pořadím metod. Použijeme starou hodnotu, která již neplatí.
Nastupuje volatile. Volatile podporuje i primitivní typy (viz. http://www.itnetwork.cz/index.php?… ). Používá se tam, kde je třeba synchronizovat jednu proměnnou v paměti mezi více vlákny. Nedochází k cachování její hodnoty a synchronizace hodnoty proběhne vždy při čtení nebo zápisu. Každé vlákno pracuje se stejnou hodnotou.
Pro rekapitulaci:
Synchronized synchronizuje několik metod do jedné atomické operace a
synchronizace nastává tam, kde se ji vynutíme.
Volatile synchronizuje hodnotu proměnné samo ve chvíli čtení a zápisu.
Nicméně metody sesynchronizovat nedokázalo. Od novější Javy toho umí
volatile více, nechci zde psát něco, co není přesné, ale myslím, že jsem
alespoň nastínil, kde je rozdíl. Volatile je sdílená proměnná mezi
vlákny, synchronized atomický soubor operací. Za nepřesnosti se omlouvám
Díky moc Nepřesnosti mi nevadí já potřeboval aspoň nastínit na co to je to volatile
Zobrazeno 3 zpráv z 3.