Thread Kavramı ve MultiThreading

Furkan Yesilyurt
3 min readNov 8, 2021

Yazdığımız bir uygulamada, bir metot işlendiği sırada farklı bir metot işlenemez. Yani fonksiyonlar eş zamanlı olarak işlenemez. Başka bir metodun çalışabilmesi için mevcutta işlenen metodun bitmesi gerekmektedir. Fakat gelişmiş uygulamalarda bu böyle olmayacaktır ve olmamalıdır.

Singel Thread & MultiThreading
Single Thread & MultiThreading

Thread, çalıştırdığımız her farklı blok için açılan kanala denir. Açılan her kanal eş zamanlı olarak tek bir iş yapabilme kabiliyetine sahiptir. Kısaca N adet thread N adet iş yapabilir diyebiliriz. Bu sayede bir işin bitmesini beklemeden başka bir iş yapabilmek için thread oluştururuz. Kullandığımız bilgisayar uygulamaları ve benzer sistemlerde de böyledir. Aynı anda farklı işlemler yapabilir, çalışmayı bekletebilir ve durdurabiliriz. Bu duruma ise multithreading denir.

Thread yapısı, uygulama işlemlerinin işlemciyi zaman paylaşımlı olarak kullanmasını sağlar. Çok çekirdekli bir sistemde iki iş parçacığının gerçekten paralel olarak çalışabilmektedir. Örnek olarak, 4 çekirdekli bir makinede, 4 iş parçacığı ile, tek bir iş parçacığına kıyasla neredeyse 4 kat daha fazla iş yapabilmekteyiz.

Thread Oluşturma

Java dilinde thread oluşturmanın iki yolu vardır.

  • ‘Thread’ sınıfını miras(extend etmek) almaktır. Fakat OOP(Object Oriented Programming)’nin ana prensibinden biri olan Inheritance konusu birden fazla sınıfın miras alınmasına izin vermemektedir.

Yukarı kod parçacığında görüldüğü gibi OrnekThread sınıfı Thread sınıfından miras almaktadır. Main metodu içerisinde bu sınıftan nesne oluşturuyoruz ve kanalı başlatmak için start() metodunu kullanıyoruz. Bu metot çağırıldığında sınıf içerisinde run() metodu çalışır. Bu metot, thread içerisinde çalışacak işlemleri içerir. Kısacası bir sınıfın thread olabilmesi için run() metodunu override etmelidir.

  • Diğer yönetimimiz ise ‘Runnable’ arayüzünü(interface) implement etmektir. İmplementasyon işleminden sonra ‘Thread’ sınıfını miras almadığımız için bu sınıfa özel bazı metotları kullanamayacağız. Bu sebeple gerekli kodları bizim yazmamız gerekmektedir.

‘Runnable’ arayüzünün avantajı, başka sınıfları miras almaya olanak sağlamasıdır.

Thread Life Cycle
Thread Life Cycle

Thread’i Başlatmak ve Durdurmak

Thread nesnelerini başlatıp durdurmak oldukça basit. Bunun için Thread sınıfının bize sağladığı start() ve stop() metotlarını kullanmamız yeterlidir. Birden fazla thread bulunan sistemlerde daha önce başlatılan nesnenin önce çalışacağı garantisi verilemez. Threadlar, farklı çekirdeklerde yorumlandığı için işlemcinin çalışma boşluklarına göre hareket ederler.

Thread nesnelerini başlatırken dikkat edilecek bir diğer önemli nokta ise nesneyi iki kere başlatmamaktır. Bu durum ‘IllegalThreadStateException’ hatasını fırlatmasına sebep olacaktır.

Thread’i Beklemeye Almak ve Devam Ettirmek

Oluşturduğumuz kanalların çalışmasını, durmasını veya biz isteyene kadar beklemesini sağlayabiliriz. Bunun için üç yöntem bulunmaktadır.

  • Nesnemize sleep() metodu ile milisaniye cinsinden uyuması için bir süre göndererek beklemesini sağlayabiliriz.
  • yield() metodu kullanıldığında aynı önceliğe sahip thread nesnesinin çalışmasını bekler ve bu işlem bittikten sonra çalışır durumuna devam eder.
  • wait() metodu kullanarak nesneyi beklemeye alabiliriz. Tekrar çalışır duruma gelmesi için uyarılmayı bekler. Bu uyarıyı göndermek çin notify() veya notifyAll() metotları ile sağlarız.

Thread nesneleri ile çalışırken nesnenin halen çalışıp çalışmadığını kontrol etmemiz gerekebilir. Bunun için isAlive() metodu yardımımıza koşuyor. Bu metod bize boolean dönüş sağlar. Nesne halen çalışıyorsa true, durmuş ise false değerini döner.

Thread Nesnesine Öncelik Atamak

Kullanacağımız thread nesnelerinin önceliklerini değiştirebiliriz. Önceliği yüksek nesnelere işlemcide daha çok yer ayrılır. Bu sebeple nesneye ait metotlar daha fazla kez çalışmaktadır.

Bu öncelik işlemini setPrioritry() metodu ile sağlarız. Bu metot parametre olarak üç sabitten birini almaktadır. Bu sabitler;

MIN_PRIORITRY : Düşük öncelik.

NORM_PRIORITRY : Normal(varsayılan) öncelik.

MAX_PRIORITRY : Yüksek öncelik.

Thread nesnesine öncelik atayabileceğimiz gibi ilgili nesnenin önceliğini de öğrenebiliriz. getPrioritry() metodu bu işe yarar.

MultiThreading

MultiThreading, çok kanal anlamına gelmektedir. Çok kanallı programlama sayesinde birden fazla işlemi paralel olarak paylaşımlı yürütebiliriz. Bazı durumlar içerisinde birçok işlem için birçok thread yapısı kullanılabilir. Bu yapıları birbirinden bağımsız veya ortak işlemler içerebilir. Ortak işlemlerde düzgün çalışabilmesi için threadlerin senkronizasyonunun sağlanması gerekir.

Thread’lerin Senkronizasyonu

Thread nesneleriyle uygulama yazarken her zaman tek bir kanalın ilgileneceği veriler üzerinde çalışmayız. Bazı durumlarda thread nesnelerinin ortak veriler üzerinde işlem yapması gerekebilir. Böyle durumlarda veri bütünlüğünün sağlanması için thread senkronizasyonu kullanılır. Çakışmalar önlenir.

Bunu sağlamak için metodumuzu veya belli bir kod bloğunu synchronized anahtar kelimesi ile işaretleriz.

--

--