Java’da Multithreading – Bölüm 12: “Callable” ve “Future”

Thread havuzlarını incelediğimiz bölümde görmüştük: “ExecutorService” sınıfının “submit” metoduna yapılacak işleri birer “Runnable” nesnesi şeklinde geçeriz, o da her bir “Runnable” nesnesi için bir thread oluşturur ve başlatır. “submit” metodu eklediğimiz her bir “Runnable” için bir “Future” döndürür. Bu “Future” nesneleri sayesinde asenkron işletilen bu görevlerin tamamlanıp tamamlanmadığını, yoksa iptal mi edildiklerini kontrol edebilir, hatta o görevleri iptal edebiliriz. Ayrıca yine bu “Future” nesnelerini kullanarak threadlerin dönüş değerlerini elde edebiliriz. Şaşırmış olmalısınız, çünkü “Runnable” arabiriminin “run()” metodu değer döndürmez, yani “void”dir. Değer döndürme ihtiyacımız olduğu durumlarda Java eş zamanlılık kütüphanesinde yer alan “Callable” adlı arabirimi kullanabilir, “submit” metoduna görevlerimizi “Callable” nesneleri olarak geçebiliriz. “Callable” arabirimi jenerik tiplidir ve sahip olduğu tek metot olan “call()” metodu “Callable” jeneriği için belirtilen tipte bir değer döner.

Aşağıda “submit” metoduna rastgele bir sayı dönen bir “Callable” geçtik. Çıktı olaraksa “Future” nesnesi üzerinden elde ettiğimiz bu rastgele sayıyı yazdıracak:

public class Application {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();

        Future future = executorService.submit(new Callable() {
            @Override
            public Integer call() throws Exception {
                Random random = new Random();
                return random.nextInt();
            }
        });

        executorService.shutdown();

        try {
            Integer result = future.get();
            System.out.println("Sonuç: " + result);
        } catch (ExecutionException e) {
            System.out.println("Çalışma zamanı hatası!");
        } catch (InterruptedException e) {
        }
    }

}

Çıktı aşağıdakine benzer şekilde olur:

Sonuç: -574704917

“Future” sınıfının ”get()” metodu iki tür “checked” (“catch” ile yakalanması gereken) istisna belirtir: “InterruptedException” ve “ExecutionException”. İlki bir sonraki bölümde ele alacağımız threadin çalışmasının kesilmesi durumlarında fırlatılır. İkincisi yani “ExecutionException” ise “call()” metodu çalışırken herhangi bir istisna fırlatılması halinde fırlatılır.

“get()” metodu çağrıldığında threadin çalışması henüz sonlanmamışsa “get()” metodunu çağıran thread (örneğimiz için bu ana threaddir) bekletilir. “get()” metodunun zaman aşımı belirtebildiğimiz ikinci bir versiyonu daha vardır:

try {
    Integer result = future.get(10, TimeUnit.MILLISECONDS);
    System.out.println("Sonuç: " + result);
} catch (ExecutionException e) {
    System.out.println("Çalışma zamanı hatası!");
} catch (TimeoutException e) {
    System.out.println("Zaman aşımı!");
} catch (InterruptedException e) {
}

“get” metodunun bu versiyonuyla beraber ele almamız gereken istisnalara biri daha eklenir: “TimeoutException”. İsminden de anlaşılacağı üzere thread belirtilen zamanda sonlanmazsa fırlatılır.

DİKKAT! Java 8 ve Lambda severler için belirtmekte fayda var. “Callable” arabirimi bir “@FunctionalInterface” olduğu için, “submit” metoduna “Callable” arabiriminin yapısına uygun bir Lambda geçilebilir:

Future future = executorService.submit(() -> {
    Random random = new Random();
    return random.nextInt();
});
Reklamlar

Java’da Multithreading – Bölüm 12: “Callable” ve “Future”” üzerine bir yorum

Bir Yorum Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s