Статьи

Google Guava Concurrency — ListenableFuture

В своем последнем посте я рассмотрел использование класса Monitor из пакета com.google.common.util.concurrent в библиотеке Guava. В этом посте я собираюсь продолжить рассмотрение утилит параллелизма Guava и обсудить интерфейс ListenableFuture . ListenableFuture расширяет интерфейс Future из пакета java.util.concurrent, добавляя метод, который принимает прослушиватель завершения.

ListenableFuture

ListenableFuture ведет себя точно так же, как java.util.concurrent.Future но имеет метод addCallback(Runnable, ExecutorService) который выполняет обратный вызов в данном executor . Вот пример:

1
2
3
4
5
6
7
ListenableFuture futureTask = executorService.submit(callableTask)
futureTask.addListener(new Runnable() {
           @Override
           public void run() {
              ..work after futureTask completed
           }
       }, executorService);

Если отправленная задача была завершена при добавлении обратного вызова, она запустится немедленно. Использование метода addCallback имеет недостаток в том, что Runnable не имеет доступа к результату, полученному в future . Для доступа к результату Future вам потребуется использовать FutureCallback .

FutureCallback

FutureCallback принимает результаты, полученные из Future и указывает onSuccess и onFailure . Вот пример:

01
02
03
04
05
06
07
08
09
10
11
12
class FutureCallbackImpl implements FutureCallback<String> {
 
       @Override
       public void onSuccess(String result){
            .. work with result
       }
 
       @Override
       public void onFailure(Throwable t) {
           ... handle exception
       }
   }

FutureCallback присоединяется с помощью метода addCallback в классе Futures:

1
Futures.addCallback(futureTask, futureCallbackImpl);

В этот момент вы можете спросить, как получить экземпляр ListenableFuture , когда ExecutorService возвращает только Futures ? Ответ заключается в использовании ListenableExecutionService .

ListenableExecutionService

Чтобы использовать ListenableExecutionService просто украсьте экземпляр ExecutorService с помощью вызова MoreExecutors.listeningDecorator(ExecutorService) например:

1
ExecutorsService executorService = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());

Вывод

С возможностью добавления обратного вызова, будь то Runnable или FutureCallback который обрабатывает условия успеха и неудачи, ListenableFuture может стать ценным дополнением к вашему арсеналу. Я создал юнит-тест, демонстрирующий использование ListenableFuture доступного как суть . В следующем посте я Futures классе Futures , который содержит статические методы для работы с futures .

Ресурсы

Ссылка: Google Guava Concurrency — ListenableFuture от нашего партнера по JCG Билла Бекака в блоге Randomечет о кодировании .