Pure Java – 90 Thread – 07 – Atomic & volatile
Merhaba Arkadaslar,
Bu yazida Atomic kavramini ve volatile anahtar kelimesini inceleyecegiz.
Atomic action, bolunemeyen en kucuk islem/adim olarak dusunebiliriz.
Ornek ile aciklayacak olursak ;
c++ ifadesi(statement) icin su adimlar yapilir;
c degerinin mevcut degeri alinir
c degeri bir(1) artirilir.
c degeri kaydedilir(store)
Yani burada 3 tane atomic action soz konusudur. Programlama acisindan kucuk bir kod parcasi gibi gozuken c++ ifadesi atomic bir yapiya sahip degildir.
Atomic action’lar interleaved(aralikli) degildir bunun anlami atomic actionlar thread interference(karisma) tehlikesi arz etmez.
Bununla birlikte hala tum tehlikelerden korunmus demek degildir. Memory consistency error hala tehlike arz etmektedir.
Memory consistency error problemini tekrar hatirlayacak olursak ;
int counter = 0; public void increment() { counter++; System.out.println(counter); }
counter degiskeni bir artirildiktan sonra consola degeri basilmakta. Eger bu iki ifadeyi(statement) ayni thread calistiracaksa problem yok fakat counter++ ifadesini ayri thread console basilmasini ayri thread yapacak olursa bu durumda ekrana 0 basma ihtimali vardir.
Thread A ve Thread B olsun , Thread A’daki bu degisimin(c++ isleminin sonucunun) Thread B tarafindan gorunur/visible olmasinin bir garantisi yoktur.
Farkli threadler ayni ‘data/variable’ uzerinde tutarsiz oldugu durumda memory consistency error ortaya cikar.
- volatile anahtar kelimesi memory consistency error problemine karsi bir cozum saglar.
- volatile bir degiskenin degerinin degismesi diger thread’ler tarafindan her zaman gorunur hale gelir.
- Memory access’ler atomictir. primitive ya da referans variable’larin okunup/yazilmasi atomic’tir. long ve double icin bu garanti yoktur.
- volatile olarak tanimlan long ve double degiskenler icin de Memory access atomic hale gelir.
volatile bir degisken CPU cache yerine bilgisayarin main memory’sinden okunur ve CPU cache yerine main memory’sine yazilir. non-volatile degiskenler icin boyle bir garanti yoktur.
volatile anahtar kelimesi degisken uzerinde bir degisiklik olduguna diger threadler tarafindan gorunmesini/visibility garanti eder.
Birden fazla thread kullanilan bir uygulamada , non-volitale olan degiskenler performans nedeniyle CPU cache’inde tutulabilir. Bilgisayarin birden fazla CPU’su oldugunu dusunursek her thread farkli CPU uzerinde calisabilir bu nedenle her thread non-volatile olan degiskenlerin degerini CPU cache’ine farkli degerde yazabilir.
Yukaridaki memory consistency error problemine neden olabilecek ornegi tekrar inceleyecek olursak ;
int counter = 0; public void increment() { counter++; System.out.println(counter); }
Bu metot icerisinde birden fazla thread calistiginda bir thread counter++ yaparak degerini 1 yaptiginda bu deger CPU cache yazilirsa problem ortaya cikabilir. counter degiskenin non-volatile oldugu icin main memory’e yazilmasini bir garantisi yoktur.
counter degiskenini volatile olarak tanimladigimizda JVM bu degiskenin her zaman main memory’e yazilacagini ve main memory’den okunacaginin garantisini verir.
volatile int counter = 0;
Birden fazla thread degiskene ulasip son(latest) degerini almak istediklerinde(read) volatile anahtar kelimesi yeterli olacaktir.
Thread A ve Thread B volatilet bir degiskenin degerini main memory’den ayni anda alir ve ikisi de bir artirir ve tekrar main memory yazarsa beklenen deger 2 olmasi gerekirken 1 degeri yazilir.
Threa A volatile bir degiskeni main memory yazarsa , Thread B nin daha sonraki okumalari(read) problem teskil etmez. Cunku volatile bir degisken main memory yazilir ve boylelikle diger thread’ler icin visibility/okunabilirlik problemi olusmaz.
Birden fazla thread paylasilan bir degisken uzerinde read/write islemi yapiyorsa volatile anahtar kelimesi yeterli olmayacaktir. Bu durumda synchronized anahtar kelimesi kullanilmalidir.
Bir thread volatile degiskeni main memory yazar ve diger thread’ler icin son degeri(latest) main memory’den okuma garantisi vardir. non-volatile degiskenler icin boyle bir garanti yoktur.
volatile bir degiskeni main memory’e yazmak CPU cache yazmaktan daha maliyetli bir istir , gerekmedikce kullanmamaya ozen gosterelim.
Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer
Leave a Reply