Java Temelleri : MultiThreaded Programlama

advertisement
MultiThreaded Programlama
MultiThreaded Programlama
Threadlar hakkında hemen her kafanıza takılan sorunun yanıtının olduğu bir
makale
Java’da Thread’ler object olarak bulunmaktadir. Iki farkli yontemle thread’ler uzerinde calisabiliriz.
1. Standart sinifimizi Thread sinifindan extend ederek.
2. Standart sinifimizi Runnable interface’inden implement ederek.
Tüm bunlar icin thread’lerimizi java diline tanitirken, Java.Lang.Thread sinifini veya Java.Lang.Runnable interface’ini kullanmamiz
gerekmektedir. Thread sinifimizin icerisinde bulunan Run() metodunu kendisinden override edilmistir fakat biz bunu kullanirken
public bir sekilde yazmamiz gerekmektedir. Ayni zamanda void ile kullanildigindan dolayi baska hic bir argument almadan return
type’ini kullanmamiz gerekmektedir. Hem thread’ler hem de islemciler bu uygulama tarafindan soyutlandirilmis yani abstract
haline getirilmistir.
Thread Class’indan Extend Edilmesi
Thread, Java.lang.Thread sinifi tarafindan extend edilir ve yine bu sinifin Run() metodu ile thread’lerimizi olusturmus oldugumuz
nesne’nin start metodunu cagirarak calistiririz.
public class Sample01 extends Thread {
public void run() {
System.out.println("Merhaba Nano");
}
public static void main(String[] args) {
Sample01 thr1 = new Sample01();
thr1.start();
}
}
Runnable Interface’inden Implement Edilmesi
Olusturmus oldugumuz thread nesnesini, Thread sinifi icerisindeki constructor’in runnable arayuzune direkt olarak uygulayarakta
calistirabiliriz.
public class Sample02 implements Runnable {
public void run() {
System.out.println("Merhabalar Nano");
}
public static void main(String[] args) {
Sample02 MyObject = new Sample02();
Thread thr1 = new Thread(MyObject);
//Thread thr1 = new Thread(new Sample02());
thr1.start();
}
}
www.dijitalders.com
MultiThreaded Programlama
1
MultiThreaded Programlama
Thread Sinifinin Kullanimi
Thread’lerimizi calistirabilmemiz icin oncelikle olusturmus oldugumuz sinifi Thread sinifindan extend etmemiz gerekiyor.
Olusturmus oldugumuz bu sinif icerisinde tanimlayacagimiz bir thread nesnesi ile birlikte thread sinifina ait start() metodunu
kullaniriz. Burada dikkat edilmesi gereken oncelik; her bir start metodu bir tek thread icin calismaktadir. Aksi olabilecek bir
durumda RuntimeException hatasi ile karsi kasiya kalirsiniz. Burada anlasilmasi gereken diger bir ayrinti ise; Ayni thread sinifi
uzerinde birden fazla nesne olusturabiliriz bununla birlikte her bir nesnenin start() metodu kendisine ait olacaktir. Start() metodu
ile birlikte artik, paralelde calismasini istediginiz kodlarini Run() metoduna yazabilirsiniz. Start() metodu calistiktan itibaren direk
run() metodu icerisindeki kod bloklari aktif hale geliyor olacak. Her bir kanalin kendi icerisinde hangi sirayla calisacagini bilemeyiz.
Burada onemli olan run() metodu icerisindeki verilen gorevlerin zaman icerisinde diger tum kanallarla birlikte calisabiliyor
olmasidir.
Thread Oncelikleri
Run() metodu ile birlikte aktif olan tum gorevlerin thread’ler uzerinde oncelikleri bulunmaktadir. Oncelik degerleri 1′den 10′a kadar
verilebilecek bir degerdir. Oncelikleri tanimlayabilmek ve degerlerini okutabilmek icin kullanacagimiz metodlar;
public final int getPriority() ; Thread’in onceligini okur.
public final int setPriority(int newPriority); Thread’in calisma sirasindaki onceligini belirlemektedir.
Oncelikleri belirleyebilmemiz icin uc adet sabit degerimiz bulunmaktadir; Thread.MIN_PRIORITY = 1 , Thread.NORM_PRIORITY
= 5 , Thread.MAX_PRIORITY = 10 gibi…
Thread Yasam Dongusu ve Durum Diagrami
Thread Life Cycle State Diagram – Thread Yasam Dongusu ve Durum Diagrami; Java’da var olan thread durumlarini aciklayacak
olursak;
New; Yaratmis oldugumuz thread’in hazir beklemesi durumudur.
Runnable; Yaratmis oldugumuz thread’in artik calisir duruma gelmesidir.
Blocked; Thread bloklanarak, monitor lock durumu icin bekletilmektedir. Blok tekrar acildiginda yeniden runnable durumuna
gececektir.
Waiting; Bir thread’in suresiz olarak diger thread’lerin yapmis oldugu isleri tamamlayabilmesi icin o thread’in bekledigi durumdur.
Timed Waiting; Bir thread’in diger thread’in isini tamamlayabilmesi icin sadece belirli bir sure bekledigi durumdur.
Terminated; Thread’lerin tum islerinin tamamlandigi ve islemlerin sonlandigi durumdur.
Özetleyecek olursak; Bir thread icin yeni bir nesne olusturulduktan hemen sonra start() metodu ile runnable durumuna
gecmektedir. Thread’lerin ne kadar sure calisacaklarini bilemedigimiz icin egerki, uzun sureli calisan bir thread varsa ve diger
thread’lerde is eksikligi varsa bunu engelleyebilmek icin uzun sureli calisan thread’lere sleep() metodunu kullanabiliriz. Sleep()
www.dijitalders.com
MultiThreaded Programlama
2
MultiThreaded Programlama
metodu icerisindeki milisaniye’lik verilen degere gore o thread durdurulacak ve diger thread’lerin calismasi devam edecektir.
Running state’de olan yani halen calisiyor olan bir thread; wait(), sleep() ve join() metodlari ile blocked state veya waiting state
asamalarina getirtilebilir. Bu asamalarda tek bir thread, Senkronize tanimlanmis bir kod blogu icerisine gonderilerek lock haliyle o
kod bloguna baglanmis olur. Thread isini bitirdikten sonra, bekleyen ve siraya giren diger thread’lere sira gelir. Egerki, lock haline
girmis bir thread’in yeniden runnable duruma gecebilmesi icin sleep veya wait durumlarindan cikmis olmasi gerekir. Thread
islemlerini bitirdikten sonra artik terminated durumuna gecerek kendisini oldurur. Bu durumda thread, tekrardan start edilemez
hale gelir.
Sik Kullanilan Method’lar
start(); Thread tarafindan calistirilan bu method, thread’in islemleri gerceklestirmesi icin harekete gecmesini saglar. Bir nevi
hazirlik asamasidir.
run(); Thread’in yapmasi gerektigi islemleri yerine getirebilecegi bir method’tur. Direkt olarak calismaz, ancak start() method’u
tarafindan aktif bir sekilde cagirilir.
stop(); Thread’i tamamen oldurur yani durdurur. Sonrasinda yeniden calistrmak icin start method’u verilmelidir. Bunun icin
destroy() method’uda kullanilabilir.
wait(); Thread’i bekleme modundadir. Yeniden uyarilana kadar yada bekleme suresi bitene kadar bekleyecektir.
notify(); Bekleme durumundaki Thread’i uyarir ve Thread artik hazirlik moduna gecer.
sleep(); Wait metodu seklinde calisacaktir, Fakat uyku modundaki thread Interrrupt() metodu ile uyandirilmaktadir.
interrupt(); sleep() yada wait() method’lari ile uyandirilmis yada beklemeye alinmis thread’leri uyandirmak, tekrar aktif hale
getirmek icin kullanilir. Thread’in kesme durumunda olup olmadigini isInterrupted() method’u ile kontrol edebiliriz.
yield(); Bir thread’in calisma aninda diger thread’lerin calisma onceliklerini kontrol ederek kendisini anlik bir sekilde bekletip
digerlerinin calismasina izin verecektir.
join(); Belirtilecek olan thread’in vermis oldugumuz zaman parametresi ile yada o thread’in olumune kadar beklemesini saglariz.
isAlive(); Calisan thread hala aktif mi degil mi kontrol eden bir method’tur. Thread’i pasif hale getirebilmek icin, sleep(long)
method’unu kullaniriz. Aktif hale getirebilmesi icin uyarmamiz gerekmektedir bunun icinde, notify() method’u kullanilir.
Thread’ler de Senkronizasyon
Eger thread’lerinizden birisi veriyi okumaya calisiyor ve diger herhangi bir thread’iniz ayni veriyi guncellemeye calisiyorsa, malesef
bu durum paylasilan bilgi icin tutarsiz bir durum sergileyecektir cunku read / write sorununu ortaya cikmis olacaktir. Bu sorunu
Java’nin Synchronized anahtari ile giderebiliriz, bunun sayesinde artik verilere senkronizasyonla duzenli ve verimli bir sekilde erisim
saglanabilecektir.
public synchronized void Method_Name() {kod blogu} seklinde kullanacagimiz methodlar sayesinde yazmis oldugumuz kod
bloklarina ayni anda birden fazla thread’in girmesini engellemek icin gelistirilmis bir method’tur. Bu method olusturulurken
synchronized anahtar kelimesi kullanilmistir. Senkronizasyon islemini sadece kod blogunda degilde sadece belirli kod satirinda
kullanmak istiyorsak bu sefer de, o tanimlanacak kod blogu icin synchronized anahtar kelimesini kullaniriz. Bunun icin synchronized
(variable){kod blogu} seklinde kullanabiliriz. Bu kod bloklarinin icerisinde sleep() metodunun kullanilmasinin bir anlami yoktur
cunku sirada bekleyen diger thread, blok icerisinden cikamayan thread icin beklemeye devam edecektir.
Java’da Thread Monitor Kavrami
Thread Monitor, JVM yani Java sanal makinesi icin kullanilan thread’lerin durumlarini gozleyebilmemiz icin gelistirilmistir. Monitor
islemi, java’da var olan her bir nesne icin gecerlidir. Thread Monitor ile, senkronizasyona ugramis method’lara sahip nesneleri ozel
erisimi zorlayarak cagiracaktir. Bir thread senkronizasyona ugramis bir method’a sahip nesneyi cagirdigi zaman, JVM o nesne icin
monitor islemini gerceklestirecektir. Monitor bostaysa, sahibi cagirilan thread tarafindan atanmis olur. Bu da daha sonrasinda,
methodlarin devamliligi ile ilgili cagrisina izin verecektir. Eger monitor baska bir thread’e ait ise, cagirilan thread, monitor
kullanilabilir hale gelene kadar beklemeye devam edecektir. Ta ki, thread senkronizasyon method’undan cikana kadar. bu da,
thread’in kendi senkronizasyon methodunu cagirmasiyla birlikte beklemede bulundugunun bir cagrisini yapmis anlamina
gelmektedir.
Not; Bu calisma Suleyman Demirel Universitesi – Bilgisayar Muhendisligi Bolumu, Degerli Hocamiz Ali GUNES ‘in beraberinde
islenen Paralel Programlama Dersi icin hazirlanmistir.
Kaynak
http://www.sevdanurgenc.com/archives/3630
www.dijitalders.com
MultiThreaded Programlama
3
Download