Java Thread Sınıfı | 2020-03-29 tarihinde oluşturuldu.

Birden fazla işlemin tek bir program akışı içinde gerçekleştirilmesi Java'da Thread sınıfları sayesinde gerçekleştirilmektedir. Şu ana kadar yaptığımız bütün örnekler ana program akışını takip ederek gerçekleştirilen işlemleri içermekteydi. Thread (iş parçacığı) kullanımı, birden fazla işlemin tek bir akışı paylaşarak neredeyse eşzamanlı bir şekilde gerçekleşmesini sağlar.

Thread kullanımına en iyi örnek oyun uygulamalarıdır. Kelime oyunu uygulamasında kullanıcının ana ekranda oyunu oynadığını düşünelim. Biz ise tam oyunun en heyecanlı yerinde rasgele bir reklam gösterip kullanıcının bütün dikkatini reklama yöneltmek isteyelim :). Bu amaçla bizim reklamı uzaktaki bir sunucudan çekip ana ekrana basan bir kod parçası yazmamız gerekmektedir. Uzaktan dosya yükleme uzun bir işlem olduğu için  işlem sırasında oyunu bloke etmememiz gerekir. Bu yüzden Thread mantığını kullanan bir kod yazarak ana akışta hem oyunu hem de yükleme işlemini ilerleterek iki işlemin de mevcut kaynakları paylaşarak kullanmasını sağlayabiliriz. Bu sayede hem kullanıcı oyununu kesintisiz oynamaya devam eder hem de reklam dosyaları uygulamaya yüklenmiş olur.

Java'da Thread kullanan program örneği ise aşağıda verilmiştir;


public class MyThread implements Runnable {
    private int    end;
    private String name;

    public MyThread(String name, int end) {
        this.end = end;
        this.name = name;
    }

    @Override
    public void run() {
        for (int i = 0; i < end; i++) {
            System.out.println(name + " : " + i);
        }
    }
}

Thread içerisinde gerçekleştirilecek işlemler öncelikle Runnable Interface'ten üretilmiş herhangi bir sınıfta tanımlanmalıdır. Yukarıda yer alan örnek kodda MyThread adında tanımlanmış bir iş parçacığı bulunmaktadır. Runnable içerisindeki run metodu içinde ise yapılması gereken işlemler belirtilir. Örnek kod yapıcı (constructor) metot içinde verilen bir int değeri kadar sayma işlemi yapacak ve bunu konsola Thread'e verilen isimle birlikte yazacaktır.

public class ThreadLesson {
    public static void main(String[] args) {
        Thread thread1 = new Thread(new MyThread("thread1", 6));
        Thread thread2 = new Thread(new MyThread("thread2", 5), "thread2");
        thread1.start();
        thread2.start();
    }
}

MyThread adlı iş parçacığını çalıştırmak için Thread adlı sınıftan faydalanırız. Yukarıdaki örnekte farklı Thread tanımlamaları ve bunların kullanımları görülmektedir. Thread'ler tanımlanırken yapıcı içerisinde Thread'e ait bir isim de verilebilir. Yukarıdaki kodun çıktısı aşağıdaki gibidir;

thread1 : 0

thread2 : 0

thread2 : 1

thread2 : 2

thread1 : 1

thread2 : 3

thread1 : 2

thread2 : 4

thread1 : 3

thread1 : 4

thread1 : 5

Eğitimin alt başlıklarında threadler ile alakalı setPriority methodu ve Executor Sınıfı hakkında anlatımlar ve örnekler yapacağız.


Öncelik Belirleme

Bir üst ders içeriğinde anlatmış olduğumuz theradlerin çalışma önceliklerini belirlemek için setPriority metodunu kullanılmaktadır. Aşağıdaki örnekte thread3 en yüksek öneme sahipken diğeri daha az önemli olarak tanımlanmıştır.

 

public class ThreadLesson {
	   public static void main(String[] args) {
	      Thread thread1 = new Thread(new MyThread("thread1", 6));
	      Thread thread2 = new Thread(new MyThread("thread2", 5));
	      Thread thread3 = new Thread(new MyThread("thread3", 4));
	      thread3.setPriority(Thread.MAX_PRIORITY);
	      thread1.setPriority(Thread.MIN_PRIORITY);
	      thread2.setPriority(Thread.MIN_PRIORITY);
	      thread1.start();
	      thread2.start();
	      thread3.start();
	   }
	}

 

Bu örnegimizde setPriority(Thread.MAX_PRIORITY) koduyla birlikte threadimizin en öncelikli çalışmasını sağlarken, setPriority(Thread.MIN_PRIORITY) koduyla threadimizin en düşük öncelikle çalışmasını sağladık.

 

İşlemin çıktısına baktığımızda ise thread1.start() kod da daha önce olmasına rağmen thread3 önceliklendirildiği için işlemini ilk bitirir.

thread1 : 0

thread2 : 0

thread3 : 0

thread1 : 1

thread3 : 1

thread2 : 1

thread3 : 2

thread1 : 2

thread3 : 3

thread2 : 2

thread1 : 3

thread2 : 3

thread1 : 4

thread2 : 4

thread1 : 5

Bu şekilde dilediğimiz kadar iş parçası tanımlayıp eşzamanlı olarak istediğimiz kadar işlem yapabilmekteyiz. Ancak unutulmaması gereken, oluşturulan her Thread'in sistemin belleğinden ve işlemciden bir pay aldığıdır. Aşırı sayıda Thread oluşturulması mikroişlemcinin işlemler arası geçiş yapması gerektiğinden ciddi performans kayıplarına yol açacaktır. Bu işlemleri düzenlemek için bir sonraki eğitim içeriğinde Executor sınıfının özelliklerini kullanacağız.


Threadların Kontrolü ve Düzenlenmesi

Thread sayısının ve çalışmasının düzenli ve kontrollü bir şekilde gerçekleştirilmesi için Java bize Executor adında bir sınıf sunmaktadır.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ThreadLesson2 {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(5);

        for (int i = 0; i < 20; i++) {
            Thread thread = new Thread(new MyThread("thread" + i, 3));
            executor.execute(thread);
        }
        executor.shutdown();
        executor.awaitTermination(10, TimeUnit.SECONDS);
        System.out.println("Done");
    }
}

ExecutorService bize belli bir anda en fazla kaç Thread çalıştırmak istediğimizi sormaktadır. Yukarıdaki örnek newFixedThreadPool metodu ile 5 farklı iş parçasının aynı anda çalıştırılabileceği belirtilmiştir. Daha sonrasında for döngüsü içinde 20 adet Thread tanımlanmasına rağmen executor servisi gelen işleri düzene sokar ve 5 Thread üzerinde işlem gerçekleştirmez. Sonradan eklenen işlemler sıraya (queue) sokulur ve mevcut işlemler bitirildikçe çalıştırılır. Böylece sistem kaynakları işlem parçaları tarafından kontrolsüzce harcanamaz. shutdown metodu ise yeni işlem alımını durdurur ve mevcut işlemlerin bitirilmesini sağlar. awaitTermination ise mevcut işlemlerin bitirilmesi için belirli bir süre tanır ve bu sürenin sonunda ExecutorService tamamen kapatılır.

Tanımlanan işlemlerin belirli bir zaman sonra otomatik başlatılması ya da sistematik olarak belli bir frekansla çalıştırılması için Java bizlere ScheduledExecutorService adında bir sınıf sunar. Bu sistem sayesinde yapılan işlemlerin belirli bir tarihte başlamasını ya da sürekli olarak işlemin tekrar edilmesini sağlayabiliriz.


import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ThreadLesson3 {
    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);
        MyThread worker = new MyThread("Thread 1", 3);
        pool.schedule(worker, 5, TimeUnit.SECONDS);
        Thread.sleep(20000);
        pool.shutdown();
    }
}

Yukarıdaki örnekte ExecutorService yerine ScheduledExecutorService kullanılarak işlemin ileri bir tarihte gerçekleşmesi sağlanır. schedule metodu ile verilen iş parçası 5 saniye gecikmeli çalışacaktır. Thread.sleep metodu ise ana akışı durdurur ancak MyThread ile tanımlanan worker iş parçası ScheduledExecutorService tarafından çalıştırılmaktadır. Konsol çıktısı aşağıdaki gibidir;

Thread 1 : 0

Thread 1 : 1

Thread 1 : 2

Dilerseniz scheduleAtFixedRate metodu ile işlemin sürekli çalışmasını sağlayabilirsiniz.

Kaynaklar:

  • https://gelecegiyazanlar.turkcell.com.tr/konu/android/egitim/android-101/threadlerin-kontrolu-ve-duzenlenmesi
  • https://gelecegiyazanlar.turkcell.com.tr/konu/android/egitim/android-101/oncelik-belirleme-setpriority-metodu
  • https://gelecegiyazanlar.turkcell.com.tr/konu/android/egitim/android-101/threadler

YORUMLAR | Bu konuya toplam (0) yorum yapılmış


YORUM YAZ
Adınızı Girin:  * Doldurulması zorunludur



   Doğrulama Kodu


KATEGORİLER
  Genel (4)
  Güvenlik (1)
  Program (5)
  Windows (6)
  Mobil (2)
  Python 3.X (16)
  PARDUS (5)
  M.E.B. (1)
  Donanım (1)
  Java (9)
  Robotik (9)

SON YAZILARIM
  Birliktelik Kuralları (Association Rules) | 2020-04-27
  Ders 7 - Tür Dönüşümleri ve input() Fonksiyonu | 2020-04-07
  Ders 6 - Veri Türleri, type() ve len() Fonksiyonları | 2020-04-06
  Java List Interface | 2020-03-29
  Java Map Interface | 2020-03-29
  Java Set Interface | 2020-03-29
  Java Thread Sınıfı | 2020-03-29
  Java'da Tatih Biçimlendirme | 2020-03-28
  Matris Çarpımı | 2020-03-28
  Java Hata Türleri (Exceptions) | 2020-03-28