21 Mayıs 2018 Pazartesi

ExecutorService Arayüzü

Giriş
Şu satırı dahil ederiz.
import java.util.concurrent.ExecutorService;
Kalıtım hiyerarşisi şöyle
ExecutorService <--ThreadPoolExecutor veya ScheduledThreadPoolExecutor
İş Başlatma
Şu metodlar kullanılabilir.
execute(Runnable command)
submit(Callable task)
submit(Runnable task)
invokeAny(Collection<? extends Callable<T>> tasks)
invokeAll(Collection<? extends Callable<T>> tasks)
Kapatma
ExecutorService kapatılmaz ise uygulama sonlanmıyor. Bu yüzden mutlaka kapatılmalı. ExecutorService iki tane shutdown() metoduna (shutdown() ve shutdownNow()) sahip. Bu yüzden şöyle kullanılamıyor.
try (service = Executors.newSingleThreadExecutor())
{
  // Add tasks to thread executor
  
} 
Şöyle yapabiliriz.
ExecutorService service = Executors.newSingleThreadExecutor();
try (Closeable close = service::shutdown) {

}
Daha klasik bir yöntem izlemek istersek şöyle yaparız.
ExecutorService service = null;
try {
  service = Executors.newSingleThreadExecutor();
  // Add tasks to thread executor
  
} finally {
  if(service != null) service.shutdown();
}
awaitTermination metodu
İmzası şöyle.
boolean awaitTermination(long timeout, TimeUnit unit)
    throws InterruptedException;
Tüm işlerin bitinceye kadar bloke olur. Şöyle kullanılır.
ExecutorService executorService = Executors.newFixedThreadPool(10);
try {
  executorService.invokeAll(callables);
  executorService.shutdown();
  executorService.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
  ...
}
execute metodu
İmzası şöyle.
public abstract void execute(Runnable paramRunnable);
Örnek
Bu sefer Future almak için Callable nesnelerini biz sarmalıyoruz.
FutureTask<String> futureTask = new FutureTask<String>(new Callable<String>() {
  public String call() throws Exception {
    return ...;
  }
});
executor.execute(futureTask);
...
String value = futureTask.get();
invokeAll metodu
Açıklaması şöyle.
Executes the given tasks, returning a list of Futures holding their status and results when all complete.
Verilen tüm işlerin bitmesini beklemek ve sonuçlarını toplamak için kullanılır.

İmzası şöyle. Callable nesneler içeride Runnable nesneye dönecek şekilde sarmalanır.
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
                      throws InterruptedException
Verilen Callable listesindeki tüm işler bittikten sonra döner. Liste şöyle doldurulur.
List<Callable<Void>> tasks = new ArrayList<Callable<Void>>();
tasks.add(new Callable<Void>(){ ...} );
executorService.invokeAll(tasks);
isTerminated metodu
shutdown () metodu çağrıldıktan sonra tüm işler bitttiyse true döner.

isShutDown metodu
shutdown() metodu çağrılmışsa true döner.

submit metodu
Metod bir Future döndürür. Metodların imzaları şöyle. Callable bir sonuç dönebilir. Runnable ise dönmez. Runnable ve Callable kullanımı Nesneye Yönelik Programlamada güzel bir composition örneği sunuyor.
<T> Future<T> submit(Callable<T> task);
Future<?>     submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);
Birinci metodu şöyle yaparız.
Future<String> future = executor.submit(new Callable() {
  public String call() throws Exception {
    ...
    return "OK";
  }
});
İkinci metodu şöyle yaparız.
service.submit(new Runnable() {
  public void run() {
    ...
  }
});
shutdown metodu
Metodun imzası şöyle.
void shutdown();
Örnek
Tüm thread'lerin bitmesini bekler. Yeni iş kabul etmez. Şöyle yaparız:
ExecutorService es= Executors.newFixedThreadPool(3);
...
es.shutdown();
Örnek
shutdown() metodu, shutdownNow() metoduna tercih edilmeli. Çünkü çalışmakta olan işleri durdumaya zorlamaz ve bitmelerini bekler. Ayrıca hemen arkasından await çağrılmalı.
ExecutorService es = Executors.newFixedThreadPool(1);
...
executor.shutdown();
if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS){...}
Örnek
Bitmemiş işleri görmek için şöyle yaparız.
executor.shutdown();
try {
  // define how much time to wait for the completion
  if (!executor.awaitTermination(15, TimeUnit.MINUTES)) { 
    List<Runnable> incompleteTask = executor.shutdownNow();
    // do that you want with them
  }
} catch (InterruptedException e) {
  // handle or log exception
}
shutdownNow
Örnek
Şöyle yaparız. Bence bu metod shutdown varken kullanılmamalı.
ExecutorService es = Executors.newFixedThreadPool(3);
...
es.shutdownNow();
Örnek
Şöyle yaparız.
List<Runnable> incompleteTask = executor.shutdownNow();

Hiç yorum yok:

Yorum Gönder