RSS

>Threads – Synchronizing Threads

18 Feb

>Herkese merhabalar;


Bu yazımda Thread ‘lerimizi nasıl senkron ederiz buna değinmeye çalışacağım.Thread ‘lerin senkronlanması çok önemli bir konudur. Thread ‘lerle ilgili ilk yazımı okuduysanız Thread ‘lerin kendilerine ayrı bellekleri olmadığını ve ortak bir bellek sahası kullandıklarını biliyoruz.Bu ortak bellekleri kullanan Thread ‘lerin senkronizasyonunu anlatmaya çalışacağım.

Shared data kullanan Thread ‘ler ortak veriye erişmek için yarış halindedirler.Bu duruma race condition denir.Bu race condition ‘un çözülmesi önemli bir problemdir. Java bize bu problemi çözmek için syncronized anahtar kelimesini sağlıyor.Thread ‘lerin ortak kullandığı kod bölgelerine critical section da denir.Critical section ‘larda bu anahtar kelimeyi kullanmak mutex lock algoritmasından başka birşey değildir.Buradan bilgi alabilirsiniz.

Şimdi bir örnek üzerinde kavramları da açıklayarak konuyu anlamaya çalışalım. Örneğimiz şöyle olsun.Bir banka hesabımız olsun bu banka hesabından para çekmek isteyen Thread ‘lerimiz olsun.Ve para çekme koşulumuz da tabii ki çekilmek istenen paranın banka hesabında olması olsun.
public class Account {
public float total = 0;
public Account() {}
public synchronized boolean drawCash(float amount){
if (total > amount) {
System.out.println(“Aktif thread = “+Thread.currentThread().getName())
total = total– amount;
return true;
}
else
return false;
}
}
public class MyThread extends Thread {
private Account myAccount;
private float amount;
public MyThread(Account _myAccount,float _amount) {
setMyAccount(_myAccount);
this.amount = _amount;
}
@Override
public void run(){
if (getMyAccount().drawCash(this.amount)) {
System.out.println(this.getName()+”->Değişikliği yaptı. Total =“+getMyAccount().total+”Amount =“+this.amount );
}
else {
System.out.println(this.getName()+”->Değişikliği yapamadı.”+”Total =“+getMyAccount().total+”Amount =” +this.amount);
}
}
public void setMyAccount(Account myAccount) {
this.myAccount = myAccount;
}
public Account getMyAccount() {
return myAccount;
}
}

Evet ne yaptığımıza bakalım.Thread ‘lerimiz banka hesabımızı ortak kullanıyor olacaklar.Ve burda kritik bölgemiz threadlerimizin ortak kullandığı data olan total değişkeni üzerinde değişiklik yapan metod olan drawCash metodu kullanmak için bir yarış halinde olacaklardır.Ancak drawCash işlemi içinde bir koşul barındırıyor.Bu da çekilmek istenen paranın hesabımızda mevcut olması durumudur.İşte kritik nokta burada başlıyor.Eğer threadler aynı anda bu bölgeye ulaşırsa ve threadlerin istediği toplam para hesabımızda yoksa ne yapacağız?Bu problemimizi syncronized anahtar sözcüğü çözüyor.:) MyThread sınıfımızda ise yarattığımız threadler Account’umuzdan para düşmeye çalışcaklar.

Şimdi yazdığımız kodu test edelim.

public class TestClass {

public static void main(String[] args) {
Account myAccount = new Account();
myAccount.total = 150;
MyThread t1 = new MyThread(myAccount, 100);
t1.setName(“Thread 1“);
MyThread t2 = new MyThread(myAccount, 75);
t2.setName(“Thread 2“);
t1.start();
t2.start();
}
}


Kodu çalıştırdığımızda threadlerin hangisi critical section’a erken ulaşırsa ilk onun istediği para hesabımızdan düşecektir.Yani 2 farklı çıktı elde edeceğiz.Bunun sebebi ise aynı hiyerarşide olan ve aynı anda çalıştırılan threadlerin çalışma süresi ve sırası nondeterministic’tir.

1.Çıktı->
Aktif thread = Thread 2
Thread 2->Değişikliği yaptı. Total =75.0Amount =75.0
Thread 1->Değişikliği yapamadı.Total =75.0Amount =100.0
2.Çıktı->
Aktif thread = Thread 1
Thread 1->Değişikliği yaptı. Total =50.0Amount =100.0
Thread 2->Değişikliği yapamadı.Total =50.0Amount =75.0

Görüldüğü üzere critical section’da aynı anda sadece bir tane thread aktif olabiliyor.Böylece banka hesabımızda
yanlış bir durumdan kaçınmış oluyoruz.Ve şimdi Account sınıfımızda drawCash metodumuzdaki syncronized
anahtar kelimesini kaldıralım ve neler oluyor görelim.

Çıktı->
Aktif thread = Thread 2
Aktif thread = Thread 1
Thread 2->Değişikliği yaptı. Total =-25.0Amount =75.0
Thread 1->Değişikliği yaptı. Total =50.0Amount =100.0

Bir gariplik var gibi değil mi?..:) Bir hesabımızdaki paranın çekilmek istenen paradan büyük olması
koşulunu parayı çekmek için koyduk ama total = -25 gelmiş.Ve dikkatinizi çektiyse aynı anda
critical section‘da threadlerimizin ikisi de aktif.İşte bu yüzden threadlerin senkron edilmesi
çok önemli bir konudur.

Önemli Not : Çıktıları elde etmek için bir kaç defa kodunuzu çalıştırmanız gerekebilir.
Çünkü daha önce de söylediğim gibi aynı anda çalıştırılan ve aynı hiyerarşiye sahip
threadlerin çalışması nondeterministic olduğu için bir kaç defa aynı çıktıyı elde edebilirsiniz.


Herkese kolay gelsin🙂

 
Leave a comment

Posted by on February 18, 2010 in Java, Synchronizing Threads, Threads

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: