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()
, veyasleep()
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.
- Sıfırdan PHP’ye: Temel EÄŸitim Serisi ile Programlama Dünyasına Adım Atın
- Java Concurrency ve Multithreading Bölüm 5: Asenkron Akış ve Reactive Programming
- Java Concurrency ve Multithreading Bölüm 4: CompletableFuture ile Asenkron İşlemler
- Milyon Dolarlık Yazılım Projesi: PHP ile Adım Adım Geliştirme
- Java Concurrency ve Multithreading Bölüm 3: ExecutorService ve Thread Havuzları