Diskuze: Synchronized vs. Volatile

Java Java Synchronized vs. Volatile

Avatar
Fugiczek
Redaktor
Avatar
Fugiczek:

Jestli je tu někdo kdo mi vysvětlí rozdíl mezi těmito dvěma druhy budu rád :) Já jedině vím, že oboje se používá hlavně u vláken. Synchronized aby vlákna náhodou zároveň nechtěli stejnou věc, kdyby to nebylo synchronizované tak by aplikace spadla, protože by se vlákna nedohodli kdo si to vezme jako první. No a o volatile toho vím málo, vzácně se používá a to je škoda. Taková proměnná/referenční typ se necachuje a furt je uložená v procesoru a neukládá se do hlavní paměti takže je rychle přístupná, jenže nevím kdy je vhodné ji použít :(

 
Odpovědět 13.7.2012 8:23
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Fugiczek
David Čápka:

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 :)

Nahoru Odpovědět  +2 13.7.2012 9:07
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Fugiczek
Redaktor
Avatar
Odpovídá na David Čápka
Fugiczek:

Díky moc :) Nepřesnosti mi nevadí já potřeboval aspoň nastínit na co to je to volatile :)

 
Nahoru Odpovědět 13.7.2012 9:16
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.