7 Temmuz 2020 Salı

Futures Sınıfı

Giriş
Şu satırı dahil ederiz.
import com.google.common.util.concurrent.Futures;
Bu sınıfın bir çok metodu ListenableFuture parametresi alıyor.

addCallback metodu - ListenableFuture + FutureCallback
- Executor nesnesi MoreExecutors ile decorate edilen bir executor olmalı.

- FutureCallback nesnesi iki tane metod kullanır. onSuccess metodu eğer iş başarılı ise döndürülen nesne tipi ile çağrılır. onFailre metodu ise iş başarırısız ise Throwable ile çağrılır

Örnek
Şöyle yaparız.
ListenableFuture listenable = service.submit(...);
Futures.addCallback(listenable, new FutureCallback<Object>() {
  @Override
  public void onSuccess(Object o) {
    //handle on success
  }

  @Override
  public void onFailure(Throwable throwable) {
    //handle on failure
  }
})
Örnek
Şöyle yaparız.
List<AsyncTask> tasks = ...;
ListeningExecutorService pool = MoreExecutors.listeningDecorator(
  Executors.newFixedThreadPool(loaddata.size()));
List<DeferredResult<?>> retResponses = new ArrayList<>();
for (int i = 0; i < tasks.size(); i++) {


  ListenableFuture<ResponseEntity<?>> stage = pool.submit(tasks.get(i));
  Futures.addCallback(stage, new FutureCallback<ResponseEntity<?>>() {
    @Override
    public void onSuccess(ResponseEntity<?> result) {
      DeferredResult<ResponseEntity<?>>  def=new DeferredResult<>();
      def.setResult(result);
      retResponses.add(def);
    }

    @Override
    public void onFailure(Throwable t) {
      DeferredResult<?>  def=new DeferredResult<>();
      def.setErrorResult(t);
      retResponses.add( def);

    }

    });
}
addCallback metodu - ListenableFuture + FutureCallback + Executor
Açıklaması şöyle
As the documentation for Futures.addCallback states, the callback is run in the executor. Your callback is only going to be run after all of the other queued elements have completed. To fix this you could create a separate executor to just execute the callbacks, or since it seems you control the pool constructor you could create a priority queue instead of a LinkedBlockingQueue as the task queue and prioritize your callbacks.
Örnek
Şöyle yaparız.
ListeningExecutorService executor =
            MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(50));

ListenableFuture<MyObject> myAsyncObject =
            calculator.calculateSomething(input);

Futures.addCallback(myAsyncObject, new FutureCallback<MyObject>() {
  public void onSuccess(MyObject result) {
    ...
  }
  public void onFailure(Throwable thrown) {
    ...
  }
}, executor);
addListener metodu
Şöyle yaparız
ListenableFuture<Void> future = ...;
future.addListener(() -> semaphore.release(), executor);
allAsList metodu
Örnek
Şöyle yaparız.
List<ListenableFuture<T>> futures = ...;
ListenableFuture<List<T>> futureOfList = Futures.allAsList(futures);
catching metodu
Örnek
Şöyle yaparız.
ListeningScheduledExecutorService scheduledExecutorService = ...;
List<ListenableFuture<Integer>> list = new LinkedList<>();
for (int i = 1; i <= 4; i++) {
  list.add(catching(
    withTimeout(scheduledExecutorService.submit(myCallback()), 3,
                TimeUnit.SECONDS,
                scheduledExecutorService),
  TimeoutException.class, exception -> 0, scheduledExecutorService));
}
getChecked metodu
Future.get() çağrısı ExecutionException, TimeoutException fırlatabiliyor. Bu farklı exception tiplerini tek bir exception olarak elde etmek yani birleştirmek için kullanılır.
Örnek
Şöyle yaparız.
ListenableFuture<List<String>> combined = ...
try {
  String greeting = Futures.getChecked(combined, IOException.class, 2000l,
    TimeUnit.MILLISECONDS);
  System.out.println(greeting);
} catch (IOException e) {
  System.out.println("Exception: " + e.getMessage());
} finally {
  ...
}
getUnchecked metodu
Tüm exception'ları unchecked exception haline getirir. Bu metodun nasıl kullanıldığına bir türlü anlam veremedim. Burada benzer bir soru var.

immediateFuture metodu
Bitmiş yani Complete bir Future döner.
Örnek
Şöyle yaparız
@Override
public ListenableFuture<Void> loadResources() {
  fastSyncMethod();

  return Futures.immediateFuture(null);
}
transform metodu
Future'dan aldığı işi transform'a geçirir ve sonuç döner.
Örnek
Şöyle yaparız
ListenableFuture<String> future = ...
ListenableFuture<String> future2 = Futures.transform(future,
  new Function<String,String>() {
    @Override
    public String apply(String input) {
      return input.toUpperCase();
    }
});
Örnek
Şöyle yaparız.
ListeningExecutorService executorSvc = ...;
ListenableFuture<String> futureMatch = ...;

Function<String, DataObject> keyToDataObj = ...;

// using "real" executor service so transform function runs
// in the background
ListenableFuture<DataObject> futureDataObj = Futures.transform(
         futureMatch, keyToDataObj, executorSvc);
transformAsync metodu
Örnek
Şöyle yaparız.
ListenableFuture<String> futureMatch = ...;

AsyncFunction<String, DataObject> keyToDataObj =  ...;

// using DirectExecutor because the transform function
// only creates and submits a Callable
ListenableFuture<DataObject> futureDataObj = Futures.transformAsync(
  futureMatch, keyToDataObj, MoreExecutors.directExecutor());
whenAllSucceeded metodu
Şöyle yaparız
ListenableFuture<Void> future1 = ...;
ListenableFuture<Void> future2 = ...;
Futures.whenAllSucceed(future1, future2).call(releasePermit, executor);