Java Thread

Java ile aynı anda birden fazla iş yapmak için kullanılan thread sınıfı, runnable arayüzü nedir, yapısı, örnekleri ve kullanımı ile ilgili bilgiler yer alıyor.

Thread nedir?

Her bir işlemin altında çalışan alt işlemlere thread adı verilir.

Aynı anda birden fazla işlem yapmayı sağlayan yapıya thread denir.

Bu yapı sayesinde işlemler birbirlerini beklemeden kendi işlemini yapar.

Kullanıcı bir form üzerinden web isteği başlattığında web isteği cevap verene kadar kullanıcı form üzerinde işlem yapamayacaktır.

Benzer şekilde ağ programlama işlemleri sırasında karşı taraftan bir cevap beklenmeye alındığında program üzerinde işlem yapılmayacaktır.

Bu ve bunun gibi durumlarda thread yapısının kullanımı iyi bir kullanıcı deneyimi için faydalı olacaktır.

Aşağıdaki örnek thread kullanılmadan yapılmıştır.

public class ThreadOrnegi {

    public static void main(String[] args) {
        uzunBirIslem();
        System.out.println("Merhaba Thread");
    }

    private static void uzunBirIslem() {
        try {
            // Burada uzun bir işlem yapılıyor.
            Thread.sleep(5 * 1000);
            System.out.println("Uzun işlem sonucu");
        } catch (InterruptedException ex) {
            System.err.println(ex);
        }
    }

}

Örnekte basit bir Merhaba Thread yazısının yazılması için uzunBirIslem metodunun bitmesi beklenmektedir.

Thread kullanımı

Thread kullanımı için Thread sınıfını kalıtım almak(extends) veya Runnable arayüzünü uygulamak(implements) olmak üzere iki yöntem kullanılır.

Thread sınıfının kullanımı için Thread sınıfı kalıtım alındıktan sonra run metodu ezilir(override) ve gerekli komutlar yazılır.

public class ThreadOrnegi extends Thread {

    public static void main(String[] args) {
        ThreadOrnegi threadOrnegi = new ThreadOrnegi();
        threadOrnegi.start();
        System.out.println("Merhaba Thread");
    }

    @Override
    public void run() {
        try {
            // Burada uzun bir işlem yapılıyor.
            Thread.sleep(5 * 1000);
            System.out.println("Uzun işlem sonucu");
        } catch (InterruptedException ex) {
            System.err.println(ex);
        }
    }

}

NOT: main metodu da bir thread oluşturur.

Runnable arayüzünün kullanımı için arayüz metotları sınıf tarafından uygulanır(implements).

Arayüz uygulandıktan sonra Thread sınıfının kurucusuna sınıf parametre olarak geçilerek thread çalıştırılır.

public class ThreadOrnegi implements Runnable {

    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadOrnegi());
        t1.start();
        System.out.println("Merhaba Thread");
    }

    @Override
    public void run() {
        try {
            // Burada uzun bir işlem yapılıyor.
            Thread.sleep(5 * 1000);
            System.out.println("Uzun işlem sonucu");
        } catch (InterruptedException ex) {
            System.err.println(ex);
        }
    }

}

Her ikisi arasında herhangi bir fark yoktur.

NOT: Java çoklu kalıtımı desteklemediğinden Runnable arayüzünün kullanımı faydalı olacaktır.

Thread yönetimi

Birden fazla thread aynı anda tek bir kaynağı kullanmaya çalıştığında belirsiz durum ortaya çıkar.

public class ThreadOrnegi implements Runnable {

    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadOrnegi());
        Thread t2 = new Thread(new ThreadOrnegi());

        t1.start();
        t2.start();
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName());
        }
    }

}

Yukarıdaki örnek her çalıştırıldığında farklı bir sonuç verecektir.

Bu belirsizliğin önüne geçmek için thread’ler arasında senkronizasyon iyi bir şekilde yapılması gerekir.

Senkronizasyonun iyi bir şekilde yapılması için çeşitli teknikler kullanılır.

Senkronizasyon için threadler belirli bir süre durdurulabilir.

public class ThreadOrnegi implements Runnable {

    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadOrnegi(1000));
        Thread t2 = new Thread(new ThreadOrnegi(2000));

        t1.start();
        t2.start();
    }

    int sure;

    public ThreadOrnegi(int sure) {
        this.sure = sure;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(this.sure);
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName());
            }
        } catch (InterruptedException ex) {
            System.err.println(ex);
        }

    }

}

Bu yöntem senkronizasyonu sağlarken thread yapısının sağladığı avantajı ortadan kaldırır.

Diğer bir yöntem ise synchronized anahtar kelimesini kullanmaktır.

public class ThreadOrnegi implements Runnable {

    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadOrnegi());
        Thread t2 = new Thread(new ThreadOrnegi());

        t1.start();
        t2.start();
    }

    @Override
    public void run() {
        synchronized (ThreadOrnegi.class) {
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName());
            }
        }
    }

}

Diğer bir yöntem ise thread’lere öncelik vermektir.

public class ThreadOrnegi implements Runnable {

    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadOrnegi());
        t1.setPriority(Thread.MIN_PRIORITY);
        Thread t2 = new Thread(new ThreadOrnegi());
        t2.setPriority(Thread.MAX_PRIORITY);

        t1.start();
        t2.start();
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName());
        }
    }

}

NOT: Öncelik vermek thread’lerin senkron çalışmasını garanti etmez.

Java ile thread kullanımı bir sınıf kullanımından farksızdır.

Ancak thread senkronizasyonunun yapılan işlem türüne göre iyi hazırlanması gerekir.

Senkronizasyon iyi yapılmadığında beklenmedik sonuçlar ortaya çıkar ve yeterli verim alınmayabilir.

Thread yönteminin verimli bir şekilde kullanılması için ayrıca problemin-algoritmanın parçalara ayrılabiliyor olması gerekir.

Java Derslerine buradan ulaşabilirsiniz.

Hayırlı günler dilerim

Yusuf SEZER

Yusuf SEZER

Computer Engineer who interested about web technologies, algorithms, artificial intelligence and embedded systems; constantly exploring new technologies.


Bunlara'da bakmalısın!