15 Temmuz 2017 Cumartesi

Exchanger Sınıfı

Giriş
İki thread arasında nesne değiş tokuşu için kullanılır.

constructor
Şöyle yaparız.
Exchanger<String> exchanger = new Exchanger<String>();
exchange metodu
İlk thread yani consumer ikinci thread'in sonucunu okur ve ikinci thread'e boş bir string atar. Şöyle yaparız.
// Wait for thread's output
String data;
try {
  data = exchanger.exchange("");
} catch (InterruptedException e1) {
  // Handle Exceptions
}
İkinci thread bir sonuç döner. Şöyle yaparız.
try {
   exchanger.exchange(data)
} catch (InterruptedException e) {

}

Future Arayüzü

Future
Future aslında bir arayüzdür. Amacı iki thread arasında birinin döndürdüğü sonucu diğerine ulaştırmak için köprü kurmaktır. Future arayüzü reactive programlama için değildir. Bu iş için CompletableFuture kullanılır.

Executer sınıfının submit metodu Future döner. Şöyle yaparız.
Future future = executorService.submit(new Callable(){
public Object call() throws Exception {
    System.out.println("Asynchronous Callable");
    return "Callable Result";
}});

cancel metodu
Şöyle yaparız
Future<String> future = ...
future.cancel(true);
get metodu
Elimizde farklı Callable nesneleri olsun.
public class One implements Callable<Integer> {

  public Integer call() throws Exception {
    print("One...");
    Thread.sleep(6000);
    print("One!!");
    return 100;
  }
}

public class Two implements Callable<String> {

  public String call() throws Exception {
    print("Two...");
    Thread.sleep(1000);
    print("Two!!");
    return "Done";
  }
}

public class Three implements Callable<Boolean> {

  public Boolean call() throws Exception {
    print("Three...");
    Thread.sleep(2000);
    print("Three!!");
    return true;
  }
}
Bu nesneleri bir Executor'a verip sonuçları almak için şöyle yaparız.
int n = 3;
// Build a fixed number of thread pool
ExecutorService pool = Executors.newFixedThreadPool(n);
// Wait until One finishes it's task.
pool.submit(new One()).get();
// Wait until Two finishes it's task.
pool.submit(new Two()).get();
// Wait until Three finishes it's task.
pool.submit(new Three()).get();
pool.shutdown();
Çıktı olarak şunu alırız.
One...
One!!
Two...
Two!!
Three...
Three!!
get metodu - timeout
TimeoutException fırlatabilir.

Örnek 1
Şöyle yaparız.
Future<String> future = ...;
try {
  future.get(5, TimeUnit.SECONDS); //timeout is in 5 seconds
} 
catch (TimeoutException e) {
  System.err.println("Timeout");
  future.cancel(true);
}
Örnek 2
Şöyle yaparız.
ExecutorService executor = Executors.newSingleThreadExecutor();
String string = null;
try {
  Future<String> future = executor.submit(new Callable<String>() {
    public String call() throws Exception {
      // your expensive operation here.
      return "result";
      }
    });
    // Set timeout
    string = future.get(1, TimeUnit.SECONDS);
  } catch (TimeoutException e) {
    // handle timeout here or write a ExceptionMapper for TimeoutException.
  } finally {
    executor.shutdownNow();
}
isCancelled metodu
Örnek ver

isDone metodu
Şöyle yaparız.
if (future.isDone()){
  //do something
}
Future İle Paralelleştirme Örnekleri
Elimizde sadece Java 7 varsa şöyle yaparız.
ResultSet rows = ...; 

List<Future<?>> futures = new ArrayList<>();
while(rows.next())
{
  
  String path = rows.getString("path");
  int job_id = rows.getInt("job_id");
  futures.add(executor.submit(new Runnable() {
    @Override
    public void run() {
      ...
    }
  });
}
// Wait until all finished
for(Future<?> future : futures)
  futures.get();