Java’da Thread Yönetimi ve Thread Durumları Nelerdir?

Java’da thread’ler farklı durumlarda bulunabilir ve bu durumlar thread’in yaÅŸam döngüsünün bir parçasıdır. Bir thread’in yönetilmesi ve farklı durumlardaki geçiÅŸleri anlamak, Java’da concurrency (eÅŸzamanlılık) ile uÄŸraşırken kritik bir öneme sahiptir. Bu yazıda, Java’da thread yönetimi ve thread durumları üzerine detaylı bir inceleme yapacağız. Java’da thread’in çeÅŸitli durumları (thread states) ve bu durumların ne anlama geldiÄŸi hakkında bilgi edineceÄŸiz.

Thread’in YaÅŸam Döngüsü

Java’da bir thread, oluÅŸturulmasından itibaren çeÅŸitli durumlardan geçer. Bu durumlar, bir thread’in çalışma süresince belirli bir noktada ne yaptığını veya hangi aÅŸamada olduÄŸunu gösterir. Thread’ler beÅŸ ana durumda bulunabilir:

  • NEW (Yeni): Thread oluÅŸturulmuÅŸ fakat henüz baÅŸlatılmamış durumda.
  • RUNNABLE (Çalışabilir): Thread çalışmaya hazır veya çalışıyor. CPU tarafından iÅŸlenmeyi bekliyor olabilir.
  • BLOCKED (Bloklanmış): Thread, bir kilidi (lock) elde etmek için bekliyor.BLOCKED (Bloklanmış): Thread, bir kilidi (lock) elde etmek için bekliyor.
  • WAITING (Bekliyor): Thread baÅŸka bir thread’in bir eylemi tamamlamasını bekliyor.
  • TIMED_WAITING (Zamanlı Bekliyor): Thread belirli bir süre boyunca beklemeye alınmış.
  • TERMINATED (Sonlanmış): Thread görevini tamamlamış ve çalışması bitmiÅŸ.

Bu durumları ve aralarındaki geçiÅŸleri daha iyi anlamak, thread’lerin doÄŸru ÅŸekilde yönetilmesi için çok önemlidir.

1) NEW (Yeni)

Bir thread Thread sınıfının bir örneği oluşturularak yaratıldığında, fakat henüz start() metodu çağrılmadığında, thread NEW durumundadır.

Örnek:

Thread thread = new Thread(() -> {
    System.out.println("Thread çalışıyor");
});
System.out.println("Durum: " + thread.getState()); // NEW

Bu durumda thread oluşturulmuş ancak henüz çalışmaya başlamamıştır.

2) RUNNABLE (Çalışabilir)

start() metodu çaÄŸrıldıktan sonra thread RUNNABLE durumuna geçer. RUNNABLE durumda olan bir thread, CPU tarafından çalıştırılmayı bekler veya aktif olarak çalışıyordur. Java’da RUNNABLE durumu hem CPU tarafından çalıştırılmayı bekleyen hem de aktif çalışan thread’leri içerir.

Örnek:

Thread thread = new Thread(() -> {
    System.out.println("Thread çalışıyor...");
});
thread.start();
System.out.println("Durum: " + thread.getState()); // RUNNABLE

start() metodunun çağrılması ile thread, çalışmaya başlamak için sıraya girer ve RUNNABLE duruma geçer.

3) BLOCKED (Bloklanmış)

Bir thread, ortak bir kaynağı (örneÄŸin bir metod veya nesne) kilitlemek için baÅŸka bir thread’in kilidi serbest bırakmasını beklerken BLOCKED duruma geçer. Genellikle synchronized anahtar kelimesi ile korunan bir kaynaÄŸa eriÅŸmeye çalışan thread’ler bloklanabilir.

Örnek:

public class Main {
    private static final Object lock = new Object();

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread 1 kilidi aldı");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread 2 kilidi aldı");
            }
        });

        thread1.start();
        thread2.start();
    }
}

Bu örnekte, thread1 kilidi aldıktan sonra thread2, aynı kilidi serbest bırakana kadar BLOCKED durumda kalacaktır.

4) WAITING (Bekliyor)

Bir thread, baÅŸka bir thread’in bir iÅŸlemi tamamlamasını beklerken WAITING durumuna geçer. Bu duruma Object.wait() veya Thread.join() gibi yöntemler neden olabilir. WAITING durumu, belirli bir süre belirtilmeden, sınırsız olarak sürebilir.

Örnek:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("Thread 1 tamamlandı");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                thread1.join(); // thread1'in tamamlanmasını bekle
                System.out.println("Thread 2 çalışıyor");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();
    }
}

Bu örnekte, thread2, thread1 tamamlanana kadar WAITING durumunda kalacaktır. join() metodu ile thread2, thread1 bitmeden çalışmaya başlamaz.

5) TIMED_WAITING (Zamanlı Bekliyor)

Bir thread belirli bir süre boyunca beklemeye alındığında TIMED_WAITING durumuna geçer. Bu duruma Thread.sleep(long millis), Object.wait(long timeout) veya Thread.join(long millis) gibi yöntemler neden olabilir.

Örnek:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(3000); // 3 saniye bekle
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread.start();
        Thread.sleep(1000); // thread'in durumu kontrol edilmeden önce 1 saniye bekle
        System.out.println("Durum: " + thread.getState()); // TIMED_WAITING
    }
}

Bu örnekte, thread 3 saniye boyunca bekletilir ve bu sırada durumu TIMED_WAITING olacaktır.

6) TERMINATED (Sonlanmış)

Bir thread, çalışmasını tamamladığında TERMINATED durumuna geçer. Bu durumda, thread ya normal bir şekilde tamamlanmış ya da bir hata nedeniyle sonlanmış olabilir.

Örnek:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            System.out.println("Thread çalışıyor...");
        });

        thread.start();
        thread.join(); // Thread'in bitmesini bekle
        System.out.println("Durum: " + thread.getState()); // TERMINATED
    }
}

Bu örnekte, thread görevini tamamladıktan sonra TERMINATED durumuna geçer.


Thread Durumları Arasındaki Geçişler

Bir thread, yaşam döngüsü boyunca bir durumdan diğerine geçiş yapar. Bu geçişler şu şekildedir:

  • NEW → RUNNABLE: start() metodu çaÄŸrıldığında.
  • RUNNABLE → BLOCKED: Bir kilit elde edilemediÄŸinde.
  • RUNNABLE → WAITING/TIMED_WAITING: wait(), join(), veya sleep() metodları çaÄŸrıldığında.
  • RUNNABLE/WAITING → TERMINATED: run() metodu sonlandığında veya bir istisna oluÅŸtuÄŸunda.

Bu geçiÅŸleri anlamak, thread’lerin davranışını tahmin edebilmek ve thread yönetimini daha iyi yapabilmek için önemlidir.


Bu makalede, Java’da thread yönetimi ve thread state’leri detaylı bir ÅŸekilde ele aldık. Thread’lerin yaÅŸam döngüsünde geçirdiÄŸi durumları, bu durumlar arasındaki geçiÅŸleri ve her bir duruma dair örnekleri inceledik. Bu bilgiler, çoklu iÅŸ parçacığı kullanımı ile çalışan Java geliÅŸtiricileri için kritik önem taşımaktadır.