www.fatihkabakci.com

Personal Website and Computer Science TUR EN

JAVA CONCURRENT EXECUTORS(CALISTIRICILAR)

Last update: 11/11/2014 12:30:00 AM

Yazan:Fatih KABAKCI

Java.util.Concurrent paketinin önemli yapılarından bir tanesi olan Executors(Çalıştırıcılar), bir küme thread(kanal) sınıflarının çalıştırılması ve yönetilmesini basitleştiren eş zamanlı araçlardır. Executor' lar sabit ve dinamik sayıda veya bir plana göre(scheduled) çalışması tasarlanmış kanal havuzları(thread pool) oluşturur. Bu kanal havuzları her bir thread' in load edilme ve kendi run() metotlarını çağırma gecikmelerine nazaran, daha hızlı bir çalışma şekli sağlar. En önemlisi eş zamanlılığı en zarif bir şekilde uygulamaktadır. Bu zariflik kodun daha sade ve anlaşılır olmasının yanında, performans üzerinde de önemli etkisinin olabilmesi olarak gösterilebilir.

Önemli Arabirimler(Interfaces)

Executor, kanal çalıştırma fikri ile tasarlanmış, hiyerarşide en tepede bulunan arabirimdir.
ExecutorService, Executor arabirimini miras alan, kanal sonlandırma ve submit etme gibi işlemler için tasarlanmış bir arabirimdir.
ScheduledExecutorService Belirli bir zamana göre ayarlanmış kanal çalıştırma işlemleri için tasarlanmış bir arabirimdir.

Sık Kullanılan Sınıflar(Classes)

  • ThreadPoolExecutor kanal çalıştırma işlemlerini sağlar.
  • ScheduledThreadPoolExecutor belirli bir zamana göre ayarlanmış kanal çalıştırma işlemlerini sağlar.

Java eş zamanlı API içerisinde, Executor sınıfının dışında, içerisinde static olarak tanımlanmış bir takım thread oluşum metotları bulunduran Executors sınıfı bulunur. Bu sınıf ile farklı şekillerde kolaylıkla kanal havuzları oluşturabilirsiniz.

Bunlar aşağıda açıklanmaktadır.

public static ExecutorService newFixedThreadPool(int nThreads)
Sabit sayıda kanal(thread) oluşturmaya yarar.
public static ExecutorService newSingleThreadExecutor()
Tek bir sayıda kanal oluşturmaya yarar.
public static ExecutorService newCachedThreadPool()
Daha önceden oluşturulan kanallar ile birlikte yeni bir kanal havuzu oluşturur.
public static ScheduledExecutorService newSingleThreadScheduledExecutor()
Belirlenmiş bir zamana göre tek bir sayıda kanal oluşturur.
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
Belirlenmiş bir zaman göre belirli sayıda bir kanal oluşturur.

Yukarıdaki metotların bir de ThreadFactory parametresine sahip overload edilmiş diğer versiyonları da bulunur. Bu da verilen ThreadFactory nesnesine göre çalışma şekillerini değiştirir.

Bir Executor(Çalıştırıcı) verilen kanal gruplarını eş zamanlı olarak çalıştırarak performans sağlar. Aşağıda 1 den 50 ye kadar 5 adet thread' in paralel çalışma örneği verilmektedir. İlk thread 1' den 10' a kadar çalışırken, sonraki thread 11' den 20' e kadar, sonraki 21-30 şeklinde giderken, son thread ise 41' den 50' ye kadar çalışır. Amaç 1 ile 50 arasındaki adımları 5 adet kanala eşit olarak paylaştırarak, eş zamanlı çalışma sağlanması hedeflenmiştir.

Counter Thread Sınıfı

package Concurrent.Executors;

/**
 * @author www.fatihkabakci.com
 */
public class Counter implements Runnable {

   int from;
   int to;

   public Counter(int from, int to) {
      this.from = from;
      this.to = to;
   }

   @Override
   public void run() {
      for (int i = from; i <= to; i++) {
         System.out.println(Thread.currentThread().getName() + " -> " + i);
      }
   }
}

Normal şartlarda yukarıdaki Counter sınıfından 5 adet instance oluşturarak paralel sayma işlemi aşağıdaki gibi yapılabilir.

Varsayılan Yöntem(Default Java Strategy)

/**
 * 
 */

package Concurrent.Executors;

import java.util.ArrayList;

/**
 * @author www.fatihkabakci.com
 */
public class DefaultParallelCounting {
   public static void main(String[] args) {

      Runnable counters[] = {new Counter(1, 10), new Counter(11, 20), new Counter(21, 30), new Counter(31, 40), new Counter(41, 50)};
      ArrayList<Thread> threads = new ArrayList<Thread>();
      
      System.out.println("Start");
      for (Runnable counter : counters) {
         Thread thread = new Thread(counter);
         threads.add(thread);
         thread.start();
      }
      for (Thread thread : threads) {
         while (thread.isAlive());
      }
      System.out.println("Finish");
   }
}
Yukarıdaki programda her bir thread bir ArrayListte depolanarak çalışır. Tüm thread' lerin bitmesi ile Main Thread Finish yazarak tamamlanır. Nitekim yukarıdaki yapı java.util.concurrent stratejisi ile uygulanırsa aşağıdaki gibi daha soft bir kod üretilebilir.

Concurrent Strategy

/**
 * 
 */

package Concurrent.Executors;

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

/**
 * @author www.fatihkabakci.com
 */
public class ExecutorParallelCounting {
   public static void main(String[] args) {

      Runnable counters[] = {new Counter(1, 10), new Counter(11, 20), new Counter(21, 30), new Counter(31, 40), new Counter(41, 50)};
      ExecutorService executor = Executors.newFixedThreadPool(5);
      System.out.println("Start");
      for (Runnable counter : counters)
         executor.execute(counter);
      
      executor.shutdown();
      while(!executor.isTerminated());
      System.out.println("Finish");
   }
}

5 adet thread ile oluşturulan sabit uzunluklu kanal(thread) havuzu, her bir thread' i doğrudan çalıştırarak(execute) tüm kanalların yönetilmesini kendi üzerinden yürütmektedir. Bu sayede kanalların sonlandırılması ve yönetilmesi thread pool üzerinden yapılarak, daha verimli bir yöntem oluşturulabilir.

Callable ve Future Arabirimleri

Bazen bir işi daha küçük parçalara ayırıp, bu parçaları ayrı ayrı hesaplayarak sonuçları değerlendirmek isteyebilirsiniz. Bu işlemler bilgisayar bilimlerinde Paralel Hesaplama(Parallel Computing) olarak adlandırılır. Concurrent paketinde tanımlı Callable ve Future arabirimlerini kullanarak paralel hesaplama yapan uygulamaları rahatlıkla geliştirebilirsiniz.
Bunun için yapmanız gereken;
1. Sınıflarınızın Callable arabirimini uygulayarak call() metodunu override etmesi.
2. ExecutorService arabirimini uygulayan sınıf nesnesinin submit() metoduna Callable referansını göndermesi.
3. submit() metodundan dönen Future nesnesinin elde edilmesi. 
yukarıdaki işlemleri basitçe uygulayabilmektir. Böylelikle Callable ve Future arabirimlerini kullanarak paralel hesaplama işlemlerini kolaylıkla yapabilirsiniz. Konuyu daha iyi anlamak adına üst başlıklarda verilen örneğimizi geliştirelim. Daha önceden de bahsettiğimiz gibi 5 adet kanalımızın olduğunu ve 10 aralıklarında 50' ye kadar for iterasyon işlemlerini paylaştırdığımızı düşünelim. Yukarıda daha önceden anlatılan bu örnekleri Future & Callable arabirimleri kullanarak uyguladığımızda aşağıdaki programı üretebiliriz.

CallableCounter Sınıfı

package Concurrent.Executors;

import java.util.concurrent.Callable;

/**
 * @author www.fatihkabakci.com
 */
public class CallableCounter implements Callable<Integer> {

   int from;
   int to;

   public CallableCounter(int from, int to) {
      this.from = from;
      this.to = to;
   }

   @Override
   public Integer call() throws Exception {
      int sum = 0;
      for (int i = from; i <= to; i++) {
         System.out.println(Thread.currentThread().getName() + " -> " + i);
         sum = sum + i;
      }
      return sum;
   }
}

CallableParallelCounting Main Sınıfı

/**
 * 
 */

package Concurrent.Executors;

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

/**
 * @author www.fatihkabakci.com
 */
public class CallableParallelCounting {
   public static void main(String[] args) throws InterruptedException, ExecutionException {

      CallableCounter counters[] = {new CallableCounter(1, 10), 
                                    new CallableCounter(11, 20), 
                                    new CallableCounter(21, 30),
                                    new CallableCounter(31, 40), 
                                    new CallableCounter(41, 50)
                                    };

      ExecutorService executor = Executors.newFixedThreadPool(5);
      System.out.println("Start");
      for (CallableCounter counter : counters) {
         Future<Integer> future = executor.submit(counter);
         Integer result = future.get();
         System.out.println("[Result]:" + result);
      }
      
      executor.shutdown();
      while (!executor.isTerminated());
      System.out.println("Finish");
   }
}
Yukarıdaki programda her biri for döngüsü iterasyon toplamını hesaplayan 5 adet kanal bulunur. Bu kanallar sabit uzunluklu bir kanal havuzunda submit() edilerek ayrı ayrı fakat eş zamanlı olarak hesaplama işlemi gerçekleştirirler. Burası önemlidir. Çünkü 5 farklı kanal aynı işin farklı parçalarını aynı anda hesaplayarak sonuçları döndürürler. Alınan sonuçlar Future nesnelerinde saklanır ve sonuçlara bu nesnenin get() metodu sayesinde erişilir.
for (CallableCounter counter : counters) {
         Future<Integer> future = executor.submit(counter);
         Integer result = future.get();
         System.out.println("[Result]:" + result);
      }

TimeUnit Enum Sınıfı

Java Concurrent sınıflarının aynı zamanda yapılan sorgulara -maksimum bekleme süreleri de tayin eder. Aşağıda TimeUnit Enumeration sınıfında tanımlanan zaman değerleri verilmiştir.

MemberCommentDate:
guest
Bu anlaşılır ve değerli yazı için çok teşekkürler.

Mesut

12/22/2019 5:27:00 AM

Name:


Question/Comment
   Please verify the image




The Topics in Computer Science

Search this site for





 

Software & Algorithms

icon

In mathematics and computer science, an algorithm is a step-by-step procedure for calculations. Algorithms are used for calculation, data processing, and automated reasoning.

Programming Languages

icon

A programming language is a formal constructed language designed to communicate instructions to a machine, particularly a computer. It can be used to create programs to control the behavior of a machine. Java,C, C++,C#

Database

icon

A database is an organized collection of data. The data are typically organized to model aspects of reality in a way that supports processes requiring information.

Hardware

icon

Computer hardware is the collection of physical elements that constitutes a computer system. Computer hardware refers to the physical parts or components of a computer such as the monitor, memory, cpu.

Web Technologies

icon

Web development is a broad term for the work involved in developing a web site for the Internet or an intranet. Html,Css,JavaScript,ASP.Net,PHP are one of the most popular technologies. J2EE,Spring Boot, Servlet, JSP,JSF, ASP

Mobile Technologies

icon

Mobile application development is the process by which application software is developed for low-power handheld devices, such as personal digital assistants, enterprise digital assistants or mobile phones. J2ME

Network

icon

A computer network or data network is a telecommunications network that allows computers to exchange data. In computer networks, networked computing devices pass data to each other along data connections.

Operating Systems

icon

An operating system is software that manages computer hardware and software resources and provides common services for computer programs. The OS is an essential component of the system software in a computer system. Linux,Windows

Computer Science

icon

Computer science is the scientific and practical approach to computation and its applications.A computer scientist specializes in the theory of computation and the design of computational systems.