Java Threads kod örnekleri ile ExecuterService nedir? Neden kullanılır? Avantajları nelerdir? Dezavantajları nelerdir? Mülakat soruları ve cevapları


ExecutorService, Java'nın java.util.concurrent paketinde yer alan bir arayüzdür. İş parçacığı (thread) havuzunu yönetmek ve iş parçacığı tabanlı çoklu görev yürütmek için kullanılır. ExecutorService, yüksek düzeyde bir arayüz sağlar ve gelişmiş bir iş parçacığı yönetimi sağlar.




ExecutorService kullanmanın bazı nedenleri şunlardır:


İş parçacığı oluşturma ve yönetme işlemlerini gizler: ExecutorService, iş parçacığı oluşturma ve yönetmeyle ilgili tüm karmaşıklığı gizler. Bu sayede geliştiriciler, iş parçacığı oluşturma, başlatma ve sonlandırma gibi düşük seviyeli detaylarla uğraşmak zorunda kalmadan daha yüksek seviyeli bir arayüz üzerinden işlerini gerçekleştirebilirler.


İş parçacığı havuzunu kullanarak performansı artırır: ExecutorService, bir iş parçacığı havuzu kullanarak işleri dağıtabilir ve aynı anda birden çok işi eşzamanlı olarak çalıştırabilir. Bu, sistem kaynaklarını daha etkin bir şekilde kullanmanızı ve performansı artırmanızı sağlar.


İşler arasındaki iletişimi ve senkronizasyonu yönetir: ExecutorService, iş parçacıkları arasındaki iletişimi ve senkronizasyonu yönetmek için çeşitli mekanizmalar sağlar. Örneğin, Future nesnelerini kullanarak işin sonucunu elde edebilir veya başka bir iş parçacığı üzerinde beklemek için CountDownLatch veya CyclicBarrier gibi senkronizasyon araçlarını kullanabilirsiniz.


ExecutorService'in bazı avantajları şunlardır:


Daha iyi performans: İş parçacığı havuzunu kullanarak çoklu görevleri eşzamanlı olarak yürütebilir ve böylece performansı artırabilirsiniz. İş parçacıklarını tekrar tekrar oluşturmak yerine, havuzdaki mevcut iş parçacıklarını kullanabilirsiniz.


Kaynak yönetimi: ExecutorService, iş parçacıklarının oluşturulmasını ve sonlandırılmasını otomatik olarak yönetir. Bu sayede, kaynakların etkin bir şekilde kullanılmasını sağlar ve olası hataları en aza indirir.


İş parçacıkları arasındaki iletişimi kolaylaştırır: ExecutorService, iş parçacıkları arasında iletişim ve senkronizasyon için hazır araçlar sağlar. Bu sayede, iş parçacıkları arasında veri paylaşımı veya senkronizasyonu kolayca gerçekleştirebilirsiniz.


Bununla birlikte, ExecutorService'in bazı dezavantajları da vardır:


Kaynak tükenmesi: Eğer iş parçacığı havuzunda çok fazla iş parçacığı oluşturursanız, sistem kaynaklarının tükenmesine neden olabilirsiniz. Bu durumda, performans yerine sistem performansı düşebilir.


İş parçacığı oluşturma maliyeti: Her iş parçacığı oluşturma işlemi bir maliyete sahiptir. Eğer çok küçük işler için sürekli olarak yeni iş parçacıkları oluşturursanız, bu iş parçacığı oluşturma maliyeti zamanla artabilir.


Java'da ExecutorService kullanarak bir iş parçacığı havuzu oluşturmanın örnek kodu aşağıdaki gibidir:


java

Copy code

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;


public class Example {


    public static void main(String[] args) {

        // İş parçacığı havuzu oluşturma

        ExecutorService executor = Executors.newFixedThreadPool(5);


        // İşleri havuza gönderme

        for (int i = 0; i < 10; i++) {

            Runnable worker = new WorkerThread("Task " + i);

            executor.execute(worker);

        }


        // İş parçacığı havuzunu kapatma

        executor.shutdown();

        while (!executor.isTerminated()) {

            // Havuzun tamamen sonlandırılmasını bekleyin

        }


        System.out.println("İşler tamamlandı.");

    }

}


class WorkerThread implements Runnable {

    private String taskName;


    public WorkerThread(String taskName) {

        this.taskName = taskName;

    }


    public void run() {

        System.out.println(Thread.currentThread().getName() + " çalışıyor - " + taskName);

        // İş parçacığı tarafından gerçekleştirilecek görevi burada tanımlayın

    }

}

Bu örnekte, ExecutorService'in bir örneği olan executor oluşturuluyor. Ardından, execute() yöntemi kullanılarak işler havuza gönderiliyor. WorkerThread sınıfı, her bir işi temsil eden iş parçacığı görevini gerçekleştiriyor. İşler tamamlandıktan sonra shutdown() yöntemi ile havuz kapatılıyor ve isTerminated() yöntemi ile tamamen sonlandırılması bekleniyor.


Bu şekilde, ExecutorService kullanarak iş parçacığı havuzunu yönetebilir ve işleri daha verimli bir şekilde yürütebilirsiniz.


Senaryo 1: Birden çok işi eşzamanlı olarak yürütmek


java

Copy code

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;


public class Example {


    public static void main(String[] args) {

        // İş parçacığı havuzu oluşturma

        ExecutorService executor = Executors.newFixedThreadPool(3);


        // İşleri havuza gönderme

        executor.execute(new WorkerThread("Task 1"));

        executor.execute(new WorkerThread("Task 2"));

        executor.execute(new WorkerThread("Task 3"));


        // İş parçacığı havuzunu kapatma

        executor.shutdown();

    }

}


class WorkerThread implements Runnable {

    private String taskName;


    public WorkerThread(String taskName) {

        this.taskName = taskName;

    }


    public void run() {

        System.out.println(Thread.currentThread().getName() + " çalışıyor - " + taskName);

        // İş parçacığı tarafından gerçekleştirilecek görevi burada tanımlayın

    }

}

Bu örnekte, newFixedThreadPool(3) yöntemiyle iş parçacığı havuzu oluşturuluyor ve 3 iş gönderiliyor. Havuz, maksimum 3 iş parçacığına sahip olacak ve bu işler eşzamanlı olarak yürütülecektir.


Senaryo 2: İşlerin sonuçlarını elde etmek




java

Copy code

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;


public class Example {


    public static void main(String[] args) {

        // İş parçacığı havuzu oluşturma

        ExecutorService executor = Executors.newFixedThreadPool(2);


        // İşleri havuza gönderme ve Future nesnelerini alıma

        Future<Integer> result1 = executor.submit(new CalculationTask(5));

        Future<Integer> result2 = executor.submit(new CalculationTask(10));


        // Sonuçları elde etme

        try {

            int sum = result1.get() + result2.get();

            System.out.println("Toplam: " + sum);

        } catch (Exception e) {

            e.printStackTrace();

        }


        // İş parçacığı havuzunu kapatma

        executor.shutdown();

    }

}


class CalculationTask implements Callable<Integer> {

    private int number;


    public CalculationTask(int number) {

        this.number = number;

    }


    public Integer call() throws Exception {

        // İş parçacığı tarafından gerçekleştirilecek hesaplama görevini burada tanımlayın

        int sum = 0;

        for (int i = 1; i <= number; i++) {

            sum += i;

        }

        return sum;

    }

}

Bu örnekte, submit() yöntemiyle işler havuza gönderilir ve her bir işin sonucunu temsil eden Future nesneleri elde edilir. Daha sonra get() yöntemi kullanılarak Future nesnelerinden sonuçlar alınır. Sonuçlar elde edildikten sonra iş parçacığı havuzu kapatılır.


ExecutorService, Java'da çoklu iş parçacığı yürütmek için güçlü bir araçtır. İş parçacığı havuzunu yönetmek, performansı artırmak ve iş parçacıkları arasında iletişimi kolaylaştırmak için kullanılabilir. Ancak, iş parçacığı sayısının dikkatlice yönetilmemesi ve iş parçacığı oluşturma maliyetinin göz ardı edilmesi gibi durumlarda dezavantajlara yol açabilir. Bu nedenle, ExecutorService'i kullanırken, uygulamanızın gereksinimlerine uygun olarak iş parçacığı sayısını ve kaynak kullanımını dikkatlice ayarlamalısınız.

Senaryo 3: İş Parçacığı Havuzu İçinde Belirli Aralıklarla Tekrarlanan Görevler


java

Copy code

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;


public class Example {


    public static void main(String[] args) {

        // İş parçacığı havuzu oluşturma

        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);


        // Görevi belirli aralıklarla tekrar etmesi için planlama

        executor.scheduleAtFixedRate(new Task(), 0, 1, TimeUnit.SECONDS);


        // Belirli bir süre sonra iş parçacığı havuzunu kapatma

        try {

            Thread.sleep(5000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        executor.shutdown();

    }

}


class Task implements Runnable {

    public void run() {

        System.out.println("Görev çalışıyor...");

        // İş parçacığı tarafından gerçekleştirilecek görevi burada tanımlayın

    }

}

Bu örnekte, newScheduledThreadPool(1) yöntemiyle iş parçacığı havuzu oluşturulur ve belirli aralıklarla tekrar eden bir görev planlanır. scheduleAtFixedRate() yöntemi kullanılarak görev belirli bir süre sonra başlatılır ve belirtilen aralıklarla tekrarlanır. Daha sonra Thread.sleep() yöntemiyle havuzun belirli bir süre çalışmasını bekleriz ve ardından havuzu kapatırız.


Senaryo 4: İş Parçacığı Havuzunda Senkronizasyon Araçları Kullanma


java

Copy code

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;


public class Example {


    public static void main(String[] args) {

        // İş parçacığı havuzu oluşturma

        ExecutorService executor = Executors.newFixedThreadPool(2);


        // Senkronizasyon aracı olarak CountDownLatch kullanma

        final CountDownLatch latch = new CountDownLatch(3);


        // İşleri havuza gönderme

        executor.execute(new WorkerThread(latch, "Task 1"));

        executor.execute(new WorkerThread(latch, "Task 2"));

        executor.execute(new WorkerThread(latch, "Task 3"));


        // Tüm işlerin tamamlanmasını bekleyin

        try {

            latch.await();

        } catch (InterruptedException e) {

            e.printStackTrace();

        }


        // İş parçacığı havuzunu kapatma

        executor.shutdown();

    }

}


class WorkerThread implements Runnable {

    private CountDownLatch latch;

    private String taskName;


    public WorkerThread(CountDownLatch latch, String taskName) {

        this.latch = latch;

        this.taskName = taskName;

    }


    public void run() {

        System.out.println(Thread.currentThread().getName() + " çalışıyor - " + taskName);

        // İş parçacığı tarafından gerçekleştirilecek görevi burada tanımlayın

        try {

            TimeUnit.SECONDS.sleep(2);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        latch.countDown();

    }

}

Bu örnekte, CountDownLatch senkronizasyon aracını kullanarak iş parçacığı havuzunda görevlerin senkronize bir şekilde tamamlanmasını sağlıyoruz. Her iş parçacığı, görevi tamamladığında latch.countDown() yöntemini çağırarak bir sayaç değerini azaltır. Ana programda ise latch.await() yöntemi kullanılarak tüm işlerin tamamlanmasını bekleriz.


ExecutorService, iş parçacığı yönetimi için güçlü ve esnek bir araçtır. Farklı senaryolara uygun olarak iş parçacığı havuzunu oluşturabilir ve işleri yönetebilirsiniz. Bu sayede, çoklu görev yürütmeyi daha verimli hale getirebilir, iş parçacığı oluşturma ve yönetme işlemlerini kolaylaştırabilirsiniz. Ancak, iş parçacığı sayısı ve kaynak kullanımı gibi faktörleri dikkatlice ayarlamak önemlidir. Ayrıca, senkronizasyon ve iletişim gerektiren durumlarda uygun senkronizasyon araçlarını kullanmak önemlidir.


Senaryo 5: İş Parçacığı Havuzunda Gelecekte Gerçekleşecek Görevleri Planlama


java

Copy code

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;


public class Example {


    public static void main(String[] args) {

        // İş parçacığı havuzu oluşturma

        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);


        // Gelecekte gerçekleşecek bir görevi planlama

        executor.schedule(new Task(), 5, TimeUnit.SECONDS);


        // Belirli bir süre sonra iş parçacığı havuzunu kapatma

        try {

            Thread.sleep(10000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        executor.shutdown();

    }

}


class Task implements Runnable {

    public void run() {

        System.out.println("Gelecekte gerçekleşecek görev çalıştı.");

        // İş parçacığı tarafından gerçekleştirilecek görevi burada tanımlayın

    }

}

Bu örnekte, schedule() yöntemi kullanılarak gelecekte gerçekleşecek bir görev planlanır. Görev, belirli bir süre sonra (5 saniye) iş parçacığı havuzunda çalıştırılacaktır. Daha sonra Thread.sleep() yöntemiyle havuzun belirli bir süre çalışmasını bekleriz ve ardından havuzu kapatırız.


Senaryo 6: İş Parçacığı Havuzunda İş Parçacıkları Arasında Veri Paylaşımı


java

Copy code

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;


public class Example {


    public static void main(String[] args) {

        // İş parçacığı havuzu oluşturma

        ExecutorService executor = Executors.newFixedThreadPool(2);


        // Paylaşılan veriyi kullanarak işleri havuza gönderme

        SharedData sharedData = new SharedData();

        executor.execute(new WorkerThread(sharedData, "Task 1"));

        executor.execute(new WorkerThread(sharedData, "Task 2"));


        // İş parçacığı havuzunu kapatma

        executor.shutdown();

    }

}


class WorkerThread implements Runnable {

    private SharedData sharedData;

    private String taskName;


    public WorkerThread(SharedData sharedData, String taskName) {

        this.sharedData = sharedData;

        this.taskName = taskName;

    }


    public void run() {

        System.out.println(Thread.currentThread().getName() + " çalışıyor - " + taskName);

        // Paylaşılan veriye erişerek işi gerçekleştirme

        int data = sharedData.getData();

        System.out.println(taskName + " tarafından paylaşılan veri: " + data);

        // İş parçacığı tarafından gerçekleştirilecek görevi burada tanımlayın

    }

}


class SharedData {

    private int data;


    public SharedData() {

        this.data = 100;

    }


    public int getData() {

        return data;

    }

}

Bu örnekte, SharedData adında bir sınıf oluşturduk ve bu sınıf paylaşılan bir veri tutuyor. İş parçacığı havuzunda çalışan her iş parçacığı, SharedData nesnesine erişerek veriyi alıyor ve kullanıyor. Bu sayede iş parçacıkları arasında veri paylaşımı gerçekleştirilmiş oluyor.


ExecutorService, iş parçacığı havuzu yönetimini kolaylaştıran bir araçtır. Farklı senaryolara göre iş parçacığı havuzunu yapılandırabilir ve işleri yönetebilirsiniz. Bu sayede, çoklu görev yürütme, performans iyileştirmesi, senkronizasyon ve veri paylaşımı gibi iş parçacığı yönetimi konularında kolaylık sağlar. Yine de, iş parçacığı sayısını ve kaynak kullanımını dikkatli bir şekilde yönetmek önemlidir. Ayrıca, senkronizasyon araçlarını ve veri paylaşımı stratejilerini doğru şekilde kullanarak uygulamanızın doğruluğunu sağlamalısınız.


Senaryo 7: İş Parçacığı Havuzunda İşleri İptal Etme


java

Copy code

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;


public class Example {


    public static void main(String[] args) {

        // İş parçacığı havuzu oluşturma

        ExecutorService executor = Executors.newFixedThreadPool(2);


        // İşleri havuza gönderme ve Future nesnelerini alıma

        Future<?> future1 = executor.submit(new Task());

        Future<?> future2 = executor.submit(new Task());


        // İşleri iptal etme

        future1.cancel(true);

        future2.cancel(true);


        // İş parçacığı havuzunu kapatma

        executor.shutdown();

    }

}


class Task implements Runnable {

    public void run() {

        while (!Thread.currentThread().isInterrupted()) {

            // İş parçacığı tarafından gerçekleştirilecek görevi burada tanımlayın

        }

        System.out.println(Thread.currentThread().getName() + " işi iptal edildi.");

    }

}

Bu örnekte, submit() yöntemi kullanılarak işler havuza gönderilir ve her bir işin sonucunu temsil eden Future nesneleri alınır. Ardından, cancel() yöntemi ile işler iptal edilir. cancel(true) parametresi, işin çalıştırıldığı iş parçacığına iptal sinyali gönderir.


Senaryo 8: İş Parçacığı Havuzunda İstisnaları Yakalama


java

Copy code

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;


public class Example {


    public static void main(String[] args) {

        // İş parçacığı havuzu oluşturma

        ExecutorService executor = Executors.newFixedThreadPool(2);


        // İşleri havuza gönderme

        executor.execute(new Task());

        executor.execute(new Task());


        // İş parçacığı havuzunu kapatma

        executor.shutdown();

    }

}


class Task implements Runnable {

    public void run() {

        try {

            // İş parçacığı tarafından gerçekleştirilecek görevi burada tanımlayın

            throw new Exception("Bir istisna oluştu.");

        } catch (Exception e) {

            System.err.println(Thread.currentThread().getName() + " işinde hata oluştu: " + e.getMessage());

        }

    }

}

Bu örnekte, iş parçacığı havuzunda çalıştırılan her işin içinde bir istisna oluşturuyoruz. try-catch bloğu içinde istisnayı yakalayarak hatayı işliyoruz. System.err.println() yöntemiyle hata mesajını konsola yazdırıyoruz.


ExecutorService, Java'da iş parçacığı yönetimini kolaylaştıran güçlü bir araçtır. Çeşitli senaryolara uygun olarak iş parçacığı havuzunu yapılandırabilir ve işleri yönetebilirsiniz. Bu sayede, çoklu görev yürütme, performans iyileştirmesi, senkronizasyon, veri paylaşımı ve iş iptali gibi iş parçacığı yönetimi konularında kolaylık sağlar. Ancak, iş parçacığı sayısını, kaynak kullanımını ve hata yönetimini dikkatli bir şekilde ele almanız önemlidir.


ExecuterService mülakat soruları ve cevapları


İşte ExecutorService ile ilgili mülakat soruları ve cevapları:


Soru 1: ExecutorService nedir?


Cevap: ExecutorService, Java'nın java.util.concurrent paketinde yer alan bir arayüzdür. İş parçacığı havuzunu yönetmek ve iş parçacığı tabanlı çoklu görev yürütmek için kullanılır. ExecutorService, yüksek düzeyde bir arayüz sağlar ve gelişmiş bir iş parçacığı yönetimi sağlar.


Soru 2: ExecutorService'in avantajları nelerdir?


Cevap: ExecutorService kullanmanın bazı avantajları şunlardır:


Daha iyi performans: İş parçacığı havuzu kullanarak çoklu görevleri eşzamanlı olarak yürütebilir ve performansı artırabilirsiniz.

Kaynak yönetimi: ExecutorService, iş parçacıklarının oluşturulmasını ve sonlandırılmasını otomatik olarak yönetir. Bu sayede, kaynakların etkin bir şekilde kullanılmasını sağlar ve hataları en aza indirir.

İş parçacıkları arasındaki iletişimi kolaylaştırır: ExecutorService, iş parçacıkları arasında iletişim ve senkronizasyon için hazır araçlar sağlar. Bu sayede, iş parçacıkları arasında veri paylaşımı veya senkronizasyonu kolayca gerçekleştirebilirsiniz.

Soru 3: ExecutorService'in dezavantajları nelerdir?


Cevap: ExecutorService'in bazı dezavantajları şunlar olabilir:


Kaynak tükenmesi: Eğer iş parçacığı havuzunda çok fazla iş parçacığı oluşturursanız, sistem kaynaklarının tükenmesine neden olabilirsiniz. Bu durumda, performans yerine sistem performansı düşebilir.

İş parçacığı oluşturma maliyeti: Her iş parçacığı oluşturma işlemi bir maliyete sahiptir. Eğer çok küçük işler için sürekli olarak yeni iş parçacıkları oluşturursanız, bu iş parçacığı oluşturma maliyeti zamanla artabilir.

Soru 4: ExecutorService ile nasıl iş parçacığı havuzu oluşturulur?


Cevap: ExecutorService ile iş parçacığı havuzu oluşturmak için Executors sınıfının yöntemlerini kullanabilirsiniz. Örneğin, newFixedThreadPool() yöntemi ile belirli bir boyutta (sabit) iş parçacığı havuzu oluşturabilirsiniz. newCachedThreadPool() yöntemi ile dinamik olarak boyutlandırılabilen bir iş parçacığı havuzu oluşturabilirsiniz. newSingleThreadExecutor() yöntemi ile sadece tek bir iş parçacığından oluşan bir havuz oluşturabilirsiniz.


Soru 5: ExecutorService ile işleri nasıl havuza gönderebiliriz?


Cevap: İşleri havuza göndermek için execute() veya submit() yöntemlerini kullanabilirsiniz. execute() yöntemi, Runnable nesnelerini kabul ederken, submit() yöntemi Runnable veya Callable nesnelerini kabul eder ve bir Future nesnesi döndürür.


Soru 6: ExecutorService ile bir işin sonucunu nasıl elde edebiliriz?


Cevap: submit() yöntemi ile gönderilen işlerin sonucunu temsil eden Future nesneleri elde edilebilir. Future nesneleri, get() yöntemi kullanılarak işin sonucunu almanızı sağlar. get() yöntemi iş tamamlanana kadar bekler ve sonucu döndürür.


Soru 7: ExecutorService ile işleri nasıl iptal edebiliriz?


Cevap: submit() yöntemi ile gönderilen işlerin iptal edilmesi için Future nesnelerinin cancel() yöntemi kullanılır. cancel() yöntemi ile işe iptal sinyali gönderilir ve iş parçacığı içinde çalışan işin iptal edilmesi sağlanır.


Soru 8: ExecutorService ile iş parçacığı havuzunu nasıl kapatırız?


Cevap: shutdown() veya shutdownNow() yöntemlerini kullanarak iş parçacığı havuzunu kapatabilirsiniz. shutdown() yöntemi, iş parçacığı havuzuna yeni işlerin kabul edilmesini durdurur ve havuzdaki mevcut işlerin tamamlanmasını bekler. shutdownNow() yöntemi ise yeni işlerin kabul edilmesini durdurur ve havuzdaki tüm işleri iptal eder.


Bu mülakat soruları ve cevapları, ExecutorService ile ilgili temel kavramları ve kullanım senaryolarını kapsamaktadır. ExecutorService'in iş parçacığı yönetimi ve çoklu görev yürütme konularında ne kadar bilgi sahibi olduğunuzu ölçmek için kullanılabilir.


Soru 1: ExecutorService ile submit() ve execute() yöntemleri arasındaki fark nedir?


Cevap: ExecutorService'in submit() yöntemi, Runnable veya Callable nesnelerini kabul eder ve bir Future nesnesi döndürür. Bu Future nesnesi, işin sonucunu temsil eder ve get() yöntemi ile sonuç alınabilir. Öte yandan, execute() yöntemi sadece Runnable nesnelerini kabul eder ve işin sonucunu döndürmez. Yani, execute() yöntemi daha basit bir şekilde işi havuza gönderirken, submit() yöntemi daha esneklik sağlar ve işin sonucunu elde etmeyi mümkün kılar.


Soru 2: ExecutorService ile bir işin tamamlanmasını nasıl bekleyebiliriz?


Cevap: Future nesnelerini kullanarak bir işin tamamlanmasını bekleyebilirsiniz. submit() yöntemi ile gönderilen işlerin sonucunu temsil eden Future nesneleri elde edilebilir. Future nesnelerinin get() yöntemini kullanarak işin tamamlanmasını bekleyebilirsiniz. get() yöntemi, iş tamamlanana kadar bekler ve sonucu döndürür. Eğer birden fazla Future nesnesi varsa, CompletableFuture sınıfı veya CountDownLatch gibi senkronizasyon araçlarını kullanarak tüm işlerin tamamlanmasını bekleyebilirsiniz.


Soru 3: ExecutorService ile bir işin zamanlanmasını nasıl yapabiliriz?


Cevap: ScheduledExecutorService arayüzü, işlerin zamanlanmasını sağlar. Executors sınıfının newScheduledThreadPool() yöntemi kullanılarak bir ScheduledExecutorService nesnesi oluşturulabilir. Ardından, schedule() veya scheduleAtFixedRate() yöntemleri kullanılarak işler belirli bir süre sonra veya belirli aralıklarla çalıştırılabilir. schedule() yöntemi, işin belirli bir süre sonra başlatılmasını sağlar. scheduleAtFixedRate() yöntemi ise işin belirli aralıklarla düzenli olarak çalıştırılmasını sağlar.


Soru 4: ExecutorService'in shutdown() ve shutdownNow() yöntemleri arasındaki fark nedir?


Cevap: ExecutorService'in shutdown() yöntemi, iş parçacığı havuzuna yeni işlerin kabul edilmesini durdurur ve havuzdaki mevcut işlerin tamamlanmasını bekler. Yani, havuzdaki tüm işlerin bitirilmesini bekler, ancak işlemler tamamlanmadan program sonlanmaz. Diğer yandan, shutdownNow() yöntemi, iş parçacığı havuzuna yeni işlerin kabul edilmesini durdurur ve havuzdaki tüm işleri iptal eder. İşlemler anında sonlandırılır ve hangi işlerin tamamlandığına bakılmaksızın iptal edilir.


Soru 5: ExecutorService ile iş parçacığı havuzunu nasıl boyutlandırabiliriz?


Cevap: Executors sınıfının newFixedThreadPool() yöntemi ile sabit boyutlu bir iş parçacığı havuzu oluşturabilirsiniz. Bu yöntem belirli bir iş parçacığı sayısıyla bir havuz oluşturur ve her bir işi havuzdaki iş parçacıklarına dağıtır. Yine Executors sınıfının newCachedThreadPool() yöntemiyle dinamik boyutlandırılabilen bir iş parçacığı havuzu oluşturabilirsiniz. Bu yöntemde, ihtiyaç duyulan kadar iş parçacığı oluşturulur ve boşta kalan iş parçacıkları zamanla sonlandırılır.


Soru 6: ExecutorService'in yeni bir görevin başlatılmasını beklemek için hangi yöntemi kullanabiliriz?


Cevap: Future nesnelerini kullanarak yeni bir görevin başlatılmasını bekleyebilirsiniz. submit() yöntemi ile gönderilen işlerin sonucunu temsil eden Future nesnelerini alabilirsiniz. Future nesnelerinin get() yöntemini kullanarak yeni bir görevin tamamlanmasını bekleyebilirsiniz. get() yöntemi, yeni bir görev tamamlandığında sonucu döndürür.


Bu mülakat soruları ve cevapları, ExecutorService'in daha ileri düzeydeki konseptlerini ve kullanım senaryolarını kapsamaktadır. ExecutorService ile ilgili detaylı bilgi sahibi olmak ve mülakatlar için hazırlık yapmak için Java'nın java.util.concurrent paketinde yer alan diğer sınıfları (ScheduledExecutorService, CompletableFuture, Callable, vb.) da incelemeniz faydalı olacaktır.

Hiç yorum yok

Rastgele İçerik

DonanımHaber

© tüm hakları saklıdır
made with by templateszoo