Java’da ExecutorService ve Thread Havuzları

Java’da concurrency (eÅŸzamanlılık) ve multithreading (çoklu iÅŸ parçacığı) uygulamalarında, thread yönetimini verimli ve kolay bir ÅŸekilde yapmak çok önemlidir. Bu noktada, Java’nın sunduÄŸu ExecutorService ve thread havuzları devreye girer. ExecutorService, Java’nın thread’leri daha verimli ve kolay yönetebilmek için sunduÄŸu güçlü bir araçtır. Bu yazıda, ExecutorService’in ne olduÄŸunu, thread havuzlarını nasıl kullanacağımızı ve thread yönetimini nasıl daha verimli hale getirebileceÄŸimizi detaylı bir ÅŸekilde ele alacağız.

ExecutorService Nedir?

ExecutorService, Java’nın java.util.concurrent paketinde bulunan ve thread’lerin yönetimini kolaylaÅŸtırmak amacıyla kullanılan bir arayüzdür. Thread’leri manuel olarak oluÅŸturmak ve yönetmek yerine, ExecutorService kullanarak bu süreci daha kontrollü ve verimli bir ÅŸekilde gerçekleÅŸtirebilirsiniz. ExecutorService, thread’lerin yeniden kullanılmasını saÄŸlayarak sistem kaynaklarının boÅŸa harcanmasının önüne geçer ve aynı anda birden fazla iÅŸlemi daha verimli bir ÅŸekilde yönetmenize yardımcı olur.

ExecutorService Kullanarak Thread Yönetimi

ExecutorService ile bir thread havuzu oluÅŸturabilir ve belirli sayıda thread’in görevleri gerçekleÅŸtirmesini saÄŸlayabilirsiniz. Bu thread’ler iÅŸlerini bitirdikten sonra baÅŸka görevleri almak için yeniden kullanılabilir, böylece her iÅŸ için yeni bir thread oluÅŸturmaya gerek kalmaz.

Örnek: ExecutorService Kullanımı

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

public class Main {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3); // 3 thread'lik bir havuz oluÅŸtur

        for (int i = 0; i < 5; i++) {
            Runnable worker = new WorkerThread("Görev " + i);
            executor.execute(worker); // Thread havuzuna görevleri ekleyin
        }
        executor.shutdown(); // Yeni görev kabul edilmez, mevcut görevler bitirilir
        while (!executor.isTerminated()) {
        }
        System.out.println("Tüm görevler tamamlandı");
    }
}

class WorkerThread implements Runnable {
    private String message;

    public WorkerThread(String message) {
        this.message = message;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " (Başlıyor) : " + message);
        processMessage();
        System.out.println(Thread.currentThread().getName() + " (Bitti) : " + message);
    }

    private void processMessage() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Bu örnekte, Executors.newFixedThreadPool(3) ile 3 thread’lik bir havuz oluÅŸturduk ve 5 farklı görev ekledik. ExecutorService, 3 thread’i kullanarak bu görevleri paralel olarak gerçekleÅŸtirdi. Bu sayede, aynı anda çalışan thread sayısını kontrol edebilir ve kaynakları daha verimli kullanabilirsiniz.

ExecutorService Metotları

ExecutorService, thread yönetimini kolaylaştıran birçok metot sunar. Bu metotlardan bazıları şunlardır:

  • execute(Runnable command): Belirtilen görevi thread havuzuna ekler ve mevcut bir thread ile bu görevi çalıştırır.
  • shutdown(): Yeni görevlerin kabul edilmesini durdurur, fakat mevcut görevlerin bitirilmesine izin verir.
  • shutdownNow(): Tüm görevleri durdurmaya çalışır ve bekleyen görevleri çalıştırmaz.
  • isShutdown(): Executor’un kapatılıp kapatılmadığını kontrol eder.
  • isTerminated(): Tüm görevlerin tamamlanıp tamamlanmadığını kontrol eder.

Thread Havuzu (Thread Pool) Nedir?

Thread havuzu, bir uygulamada aynı anda çalışan thread sayısını kontrol etmek ve kaynak kullanımını optimize etmek için kullanılan bir tekniktir. Her yeni görev için bir thread oluÅŸturmak yerine, önceden belirlenmiÅŸ sayıda thread’in yeniden kullanılması saÄŸlanır. Bu sayede, thread oluÅŸturma ve yok etme iÅŸlemlerinin getirdiÄŸi maliyet en aza indirgenmiÅŸ olur.

Thread Havuzu Türleri

Java, farklı thread havuzu türleri sunar. Bu havuzlar, farklı kullanım senaryolarına göre seçilebilir:

1. Fixed Thread Pool

Sabit sayıda thread içeren bir havuzdur. Executors.newFixedThreadPool(int nThreads) kullanılarak oluÅŸturulur. Bu havuz, belirli sayıda thread’in yeniden kullanılmasını saÄŸlar.

ExecutorService fixedPool = Executors.newFixedThreadPool(4);

2. Cached Thread Pool

GerektiÄŸi kadar thread oluÅŸturan ve kullanılmayan thread’leri bir süre sonra serbest bırakan bir havuzdur. Kısa süreli fakat çok sayıda görev içeren durumlarda kullanışlıdır. Executors.newCachedThreadPool() kullanılarak oluÅŸturulur.

ExecutorService cachedPool = Executors.newCachedThreadPool();

3. Single Thread Executor

Tek bir thread kullanan bir havuzdur. Görevler bir kuyruğa alınır ve sırayla gerçekleştirilir. Executors.newSingleThreadExecutor() kullanılarak oluşturulur.

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

4. Scheduled Thread Pool

Belirli aralıklarla veya belirli bir süre sonra görevlerin çalıştırılması için kullanılır. Executors.newScheduledThreadPool(int corePoolSize) kullanılarak oluşturulur.

ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(2);

Fixed Thread Pool vs Cached Thread Pool

  • Fixed Thread Pool: Sabit sayıda thread kullanarak belirli sayıda görevi paralel olarak çalıştırır. Sistemin kapasitesine göre kaç thread kullanılacağını ayarlamak mümkündür. Sabit görev sayısının olduÄŸu durumlarda kullanışlıdır.
  • Cached Thread Pool: GerektiÄŸi kadar yeni thread oluÅŸturur ve bu thread’ler kullanılmadığında serbest bırakılır. Kısa süreli ve çok sayıda küçük görevler için uygundur, ancak uzun süreli görevlerde çok fazla thread oluÅŸarak sistem kaynakları tüketilebilir.

ExecutorService ve Thread Havuzlarının Avantajları

  • Kaynak Yönetimi: Thread’lerin yeniden kullanılması, thread oluÅŸturma ve yok etme maliyetini azaltır. Bu sayede sistem kaynakları daha verimli kullanılır.
  • Kolay Yönetim: ExecutorService, thread’lerin yönetimiyle ilgili karmaşıklığı azaltır. Thread’leri manuel olarak yönetmek yerine, görevlerin belirli bir thread havuzunda sıraya alınmasını saÄŸlar.
  • Ölçeklenebilirlik: Thread havuzları, iÅŸ yükünü dengelemek ve uygulamanın performansını artırmak için ölçeklenebilir bir çözüm sunar.

Örnek: ScheduledExecutorService Kullanımı

ScheduledExecutorService, görevlerin belirli bir süre sonra veya belirli bir aralıkla çalıştırılmasını sağlar. Örneğin, belirli bir görevi her 5 saniyede bir çalıştırmak için kullanılabilir.

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

public class Main {
    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        Runnable task = () -> System.out.println("Zamanlı görev çalışıyor: " + System.currentTimeMillis());

        scheduler.scheduleAtFixedRate(task, 0, 5, TimeUnit.SECONDS); // Her 5 saniyede bir çalıştır
    }
}

Bu örnekte, scheduleAtFixedRate() metodu ile belirli bir görevi her 5 saniyede bir çalıştırıyoruz. Bu tür kullanım, periyodik görevler için oldukça faydalıdır.


Bu makalede, Java’da ExecutorService ve thread havuzları kullanarak thread yönetimini nasıl daha verimli hale getirebileceÄŸimizi ele aldık. ExecutorService, thread oluÅŸturma ve yönetim iÅŸlemlerini kolaylaÅŸtırarak daha güvenilir ve verimli uygulamalar geliÅŸtirmemize yardımcı olur.