Wednesday, October 31, 2001

Thread'ler

Program yazarken, kodunuza aynı anda, iki değişik işlemi yaptırma ihtiyacı hissettiniz mi?

Mesela, programınızın bir bölümü örütbağ üzerinden gelen bilgiyi depolarken, öteki tarafı aynı anda ekranda şekiller çizsin, kullanıcı girişi ile meşgul olsun.

Programlamaya başladığımızdan itibâren yarattığımız programlar, dizisel yöntemle çalışacak türdendir. Bu programların başlangıcı sonu belli, bilgisayar tarafından nasıl işletileceği hangi sırada işleyeceği bilinen programlardır. Birden fazla programı işleten işletim sistemidir, tek programın içinde bunu yaptırmak genelde lazım olmaz.

Fakat eğer, eşzamanlı çalışacak kod parçaları aynı program içinde lazım oluyorsa, ve kullandığımız dil Java ise, bize lazım olan İş Kolu denen kavramdır.

İş Parçacığı Nasıl Kullanılır

Java dili içinde İş Kolu kullanmak çok rahat. Ilk önce, eşzamanlı işleyecek kod için bir nesne yaratmak gerekiyor.

public class BizimNesne implements Runnable
{
public void run()
{
for (int i = 0; i<100; ilk_kol =" new" ikinci_kol =" new">

Yukarıdaki örnekte gördüğümüz Thread adlı nesne, kendi başına çalişabilen İş Kolu nesnesinin Java'daki halidir. Yani, Iş Parçacığı kullanmak için Java dilinde Thread nesnesini kullanmak gerekiyor.

Ayrıca, nesnesel programcılık içinde İş Kolu kullanımı ve akılda canlandırmak daha rahat, çünkü eşzamanlı programınız içinde işbölümü yaparken tek bir nesneye tek bir İş Kolu bağlarsak, hatirlamak ve kodlamak rahat oluyor.

İş Kolu kullanmanın en zor tarafı, değişik parçaların, aynı kodu (ya da nesneyi) aynı anda kullanması gerektiği durumlardadır. Bu gibi durumlarda, aynı nesnenin 'işlem ortasında' iki taraftan aynı anda değiştirilmesi hatalı kod çikaracağından, ortak kullanılması muhtemel nesnelerdeki işlemleri 'kitlemek' gerekir.

Kitlemek

Kitlenmesi gereken programları anlamak için şöyle düşünelim. Programınızı sabit varsayın ve programınızın aynı satırları üzerinden geçen değişik işlemciler olsun.

Aynı handan geçen değişik yolcular.

Bu yolcuların sadece bir tanesinin handa kalabileceğini varsayarsak, kitleme kavramını anlamaya başlayabiliriz. Java dilinde bu işi basaran 'synchronized' kelimesidir.

Kitleme yapmak, iş kolu tarafindan 'kullanılan' işlemler için gerekir. O yüzden, yukarıdaki örnekte kitleme yapmamıza gerek yok, çünkü programın kendisi zaten bir iş koludur. Fakat başka bir nesne gerektigini varsayalım.

public class BankaHesabi
{
protected int miktar;

public void paraEkle(int yatir)
{
miktar = miktar + yatir;
}

public void paraCek(int cek)
{
miktar = miktar - cek;
}
}

Bu program dahilinde mesela müşteri hesabına bağlanmış, ve para ekliyor olabilir, aynı anda banka da, faizden gelecek parayı hesaba ekliyor olsun. Eğer BankaHesabi nesnesi kendi kendini korumazsa, iki değişik işlemin aynı 'miktar' sayısına bakarak işlem yapması mümkün olabilir! Bu da programın doğru işlerliğı bakımından facia olacaktır. Müşteri hesabı yanliş çıkacak.

Bu hatayı engellemek için, programı şu şekilde değiştirmek gerekir.

public class BankaHesabi
{
protected int miktar;

public synchronized void paraEkle(int yatir)
{
miktar = miktar + yatir;
}

public synchronized void paraCel(int cek)
{
miktar = miktar - cek;
}
}

Synchronized kelimesi Java dilinde kitleme yapmak için kullanılır. Eğer bir iş kolu syncronized kelimesi içeren bir işlemi işletiyorsa, Java sanal makinesi şunları yapar.


* Işlemi kitle
* Öteki işlem kolları (varsa) onları bekleme kuyruğuna al.
* Bu gelen iş parçacığı için kodları işleme koy

Ilk gelen kolunun işi bitince, öteki parçacıklara teker teker izin verilecektir.

Ne zaman kullanılmalı

Internet ve sunucu üzerinde çalışan programların %99'unda işlem kolu kullanmak gerekmiyor. Bu tip programlar uygulama sunucusu denen öteki kodlar üzerinde işlediği için, eşzamanlı kodlama bu alt seviye program tarafından halledilmiştir.

Eşzamanlı kodlama yapmak hakkaten çetrefilli bir iştir, ve Internet sayfası sunan programlar için çok temel bir ihtiyaç olduğu için en alt kademede bu iş zaten yapilmiştir.

Mesela her kullanıcıya, aynı anda sunulan sayfa değişik Iş Kolları tarafından sunulmaktadır. Biz sayfayı tek bir kullanıcı farzederek yazarız, işin öteki tarafını uygulama sunucusu halleder (Tomcat gibi).

İş Kolunu özellikle kullanmamız gerektiği durumlar, kendi başına çalışan Java programları olabilir, eğer eşzamanlı işlemesi gereken yerler için bu programın kullanbileceği bir kutuphane erafta yok ise, o zaman bu tür kodlamayı kendimizin yapması gerekebilir.

Hız kazanımı

Ayrıca, ikinci bir Iş Parçacığı ekleyerek programımızın 2 kat hızlı çalışmasını beklemek de yanlış olur. Donanım seviyesinde düşünürsek, eğer birden fazla mikroişlemci mevcut değil ise (iki tane Pentium işlemcisi gibi) o zaman işletim sistemi mikroislemciyi iki parçacık arasında paylastıracaktır; böylece iki parçacık yarım hızda çalısır ve hiç bir kazanç olmaz.

O zaman, tek mikroislemci üzerinde parçacık kullanmak niye gerekiyor diye sorabilirsiniz ve haklısınız. Su kıstası kullanın: Eğer programınızda 'bir seyi bekleyen' ya da dıs dünyada bir seye takılıp kalan' bir kısım yoksa, birden fazla parçacık kullanmanın yararı olmayacaktır.

Programcılık genel kültürü açısından, Is Parçacığı kavramını bilmemiz ilerde ise yarayabilir.

No comments: