Java’da Thread Nedir ve Nasıl Kullanılır?
Java’da concurrency, yani aynı anda birden fazla işlemi gerçekleştirme yeteneği, günümüz yazılım dünyasında performans artırmak ve verimliliği sağlamak açısından çok önemli hale gelmiştir. Bu bağlamda, Java’da thread kavramı, çoklu iş parçacığı kullanımı (multithreading) ve aynı anda birden fazla işlemi paralel olarak yürütmek için temel yapı taşlarından biridir.
Java’da Thread Nedir?
Bir thread (iş parçacığı), bir programın bağımsız olarak çalışabilen en küçük birimidir. Java’da bir thread, programın aynı anda birden fazla iş yapabilmesini sağlar. Bu, özellikle büyük veri kümeleri üzerinde işlemler yaparken veya uzun süren görevleri yürütürken performans iyileştirmeleri sağlar. Java’daki her uygulama, JVM (Java Virtual Machine) tarafından oluşturulan ana thread (main thread) ile başlar ve bu ana thread, programın başlangıç noktasındaki kodları yürütür.
Java’da thread oluşturmanın iki temel yolu vardır:
- Thread Sınıfını Genişletmek (Extending
Thread
Class) - Runnable Arayüzünü Kullanmak (Implementing
Runnable
Interface)
Bu yöntemlerin her birini detaylı olarak inceleyeceğiz.
Thread Sınıfını Genişleterek Thread Oluşturma
Java’da thread oluşturmanın ilk yolu, Thread
sınıfını genişleterek yeni bir sınıf yaratmaktır. Bu sınıf içinde, thread’in çalıştıracağı işlemleri tanımlamak için run()
metodunu override etmemiz gerekir. run()
metodu, thread’in başlatılmasıyla beraber yürütülen işlemleri tanımlar.
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " çalışıyor: " + i);
try {
Thread.sleep(1000); // 1 saniye bekletir
} catch (InterruptedException e) {
System.out.println("Thread kesildi.");
}
}
}
}
public class Main {
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.start();
thread2.start();
}
}
Yukarıdaki örnekte, MyThread
sınıfı Thread
sınıfını genişletir ve run()
metodunu override ederek thread’in yapacağı işleri tanımlar. thread1
ve thread2
olarak iki farklı thread başlattık ve bu thread’ler aynı anda çalışmaktadır. Her biri, run()
metodunu 5 kez döngü içinde çalıştırır ve her bir iterasyondan sonra 1 saniye bekletilir.
Runnable Arayüzünü Kullanarak Thread Oluşturma
Java’da thread oluşturmanın diğer bir yöntemi ise Runnable
arayüzünü kullanmaktır. Bu yöntem, daha esnek bir çözüm sunar çünkü sınıfınız başka bir sınıfı da genişletebilirken aynı anda thread oluşturmanıza olanak tanır.
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " çalışıyor: " + i);
try {
Thread.sleep(1000); // 1 saniye bekletir
} catch (InterruptedException e) {
System.out.println("Thread kesildi.");
}
}
}
}
public class Main {
public static void main(String[] args) {
Thread thread1 = new Thread(new MyRunnable());
Thread thread2 = new Thread(new MyRunnable());
thread1.start();
thread2.start();
}
}
Yukarıdaki örnekte, Runnable
arayüzünü implement eden MyRunnable
sınıfı oluşturduk. Runnable
arayüzü ile run()
metodunu override ederek işlemimizi tanımladık. Thread
sınıfının bir örneği olarak thread1
ve thread2
nesnelerini oluşturduk ve bu thread’leri başlattık.
Thread.sleep() Kullanımı
Java’da Thread.sleep(long millis)
metodu, bir thread’in belirli bir süre beklemesini sağlar. Bu yöntem, belirli işlemler arasında bir gecikme eklemek istediğimizde kullanışlıdır. Ancak InterruptedException
atabileceği için bu hatayı try-catch
bloğu içinde ele almak önemlidir.
ublic class Main {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
for (int i = 1; i <= 3; i++) {
System.out.println("İşlem " + i);
try {
Thread.sleep(2000); // 2 saniye bekletir
} catch (InterruptedException e) {
System.out.println("Thread kesildi.");
}
}
});
thread.start();
}
}
Bu örnekte, lambda ifadesi kullanarak basit bir thread oluşturduk ve her iterasyonda 2 saniye beklemesini sağladık. Bu şekilde thread’lerin nasıl bekletilebileceğini görebilirsiniz.
Thread Önceliği (Thread Priority)
Java’da thread’lere öncelik atamak mümkündür. setPriority(int priority)
metodu ile bir thread’e öncelik verebiliriz. Java’da thread öncelikleri Thread.MIN_PRIORITY
(1), Thread.NORM_PRIORITY
(5, varsayılan), ve Thread.MAX_PRIORITY
(10) arasında bir değere sahiptir.
public class Main {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> System.out.println("Thread 1 çalışıyor"));
Thread thread2 = new Thread(() -> System.out.println("Thread 2 çalışıyor"));
thread1.setPriority(Thread.MAX_PRIORITY); // Önceliği 10 olarak ayarlandı
thread2.setPriority(Thread.MIN_PRIORITY); // Önceliği 1 olarak ayarlandı
thread1.start();
thread2.start();
}
}
Bu örnekte, thread1
maksimum önceliğe sahipken, thread2
minimum önceliğe sahiptir. Ancak, bu öncelikler işletim sistemi tarafından dikkate alınsa da her zaman garantili bir sonuç vermez; dolayısıyla kodun doğru çalışmasına bu önceliklere bağlı olarak güvenmemek önemlidir.
join() Metodu Kullanarak Thread’leri Senkronize Etme
join()
metodu, bir thread’in diğerinin bitmesini beklemesini sağlar. Bu, özellikle bir thread’in tamamlanmasını beklemeden diğerine geçilmesini önlemek için kullanılır.
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1: " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("Thread kesildi.");
}
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 2: " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("Thread kesildi.");
}
}
});
thread1.start();
thread1.join(); // thread2 başlamadan önce thread1'in bitmesini bekle
thread2.start();
}
}public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1: " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("Thread kesildi.");
}
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 2: " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("Thread kesildi.");
}
}
});
thread1.start();
thread1.join(); // thread2 başlamadan önce thread1'in bitmesini bekle
thread2.start();
}
}
Bu örnekte, thread1
‘in tamamlanmasını join()
metodu ile bekledik ve sonrasında thread2
‘yi başlattık. Bu sayede thread’ler arasında bir sıra oluşturduk.
Java’da thread kullanımı, aynı anda birden fazla iş gerçekleştirmeye olanak tanıyan çok güçlü bir araçtır. Bu makalede, thread oluşturmanın iki temel yolunu, thread yönetimini, Thread.sleep()
, join()
, ve thread önceliklerini detaylıca inceledik. Bu bilgiler, çok iş parçacıklı programlama konusuna giriş yapmak isteyen Java geliştiricileri için önemli bir temel oluşturacaktır.
- 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ı
- Milyon Dolarlık Bir Proje Kodluyoruz