Java Platform, Enterprise Edition (Java EE) 8
Учебник по Java EE

Назад Вперёд Содержание

Вызов асинхронных методов

Сессионные компоненты могут реализовывать асинхронные методы, бизнес-методы, в которых управление возвращается клиенту контейнером Enterprise-бина перед вызовом метода в объекте cессионного компонента. Затем клиенты могут использовать API параллелизма Java SE для получения результата, отмены вызова и проверки исключений. Асинхронные методы обычно используются для длительных операций, для задач с интенсивным использованием процессора, для фоновых задач, для увеличения пропускной способности приложения или для увеличения времени отклика приложения, если результат вызова метода не требуется немедленно.

Когда клиент сессионного компонента вызывает типичный не асинхронный бизнес-метод, управление не возвращается клиенту, пока метод не завершится. Однако клиенты, вызывающие асинхронные методы, немедленно получают контроль, возвращаемый им контейнером Enterprise-бинов. Это позволяет клиенту выполнять другие задачи во время выполнения вызова метода. Если метод возвращает результат, этим результатом является реализация интерфейса java.util.concurrent.Future<V>, где «V» — тип значения результата. Интерфейс Future<V> определяет методы, которые клиент может использовать для проверки завершения вычислений, ожидания завершения вызова, получения окончательного результата и отмены вызова.

Создание асинхронного бизнес-метода

Аннотируйте бизнес-метод с помощью javax.ejb.Asynchronous, чтобы пометить этот метод как асинхронный, или примените @Asynchronous на уровне класса, чтобы отметить все бизнес-методы сессионного бина как асинхронные. Методы сессионных компонентов, которые предоставляют веб-сервисы, не могут быть асинхронными.

Асинхронные методы должны возвращать либо void, либо реализацию интерфейса Future<V>. Асинхронные методы, которые возвращают void, не могут объявлять исключения приложения. Но асинхронные методы, возвращающие Future<V>, могут объявлять исключения приложения. Например:

@Asynchronous
public Future<String> processPayment(Order order) throws PaymentException { ... }

Этот метод попытается обработать оплату заказа и вернёт статус в виде String. Даже если процессор обработки платежей выполняется значительное время, клиент может продолжить работу и отобразить результат после окончательной обработки.

Класс javax.ejb.AsyncResult<V> представляет собой реализацию интерфейса Future<V>, предоставленного в качестве вспомогательного класса для возврата асинхронных результатов. AsyncResult имеет конструктор со строковым параметром-результатом, что упрощает создание реализаций Future<V>. Например, метод processPayment будет использовать AsyncResult для возврата статуса в виде String:

@Asynchronous
public Future<String> processPayment(Order order) throws PaymentException {
    ...
    String status = ...;
    return new AsyncResult<String>(status);
}

Результат возвращается в контейнер Enterprise-бина, а не непосредственно клиенту, и контейнер Enterprise-бинов делает результат доступным для клиента. Сессионный компонент может проверить, запросил ли клиент отмену вызова, вызвав метод javax.ejb.SessionContext.wasCancelled. Например:

@Asynchronous
public Future<String> processPayment(Order order) throws PaymentException {
    ...
    if (SessionContext.wasCancelled()) {
        // очистка
    } else {
        // обработка платежа
    }
    ...
}

Вызов асинхронных методов из Enterprise-бина

Сессионные компоненты вызывают асинхронные методы точно так же, как не асинхронные бизнес-методы. Если асинхронный метод возвращает результат, клиент получает объект Future<V> сразу после вызова метода. Этот объект можно использовать для получения окончательного результата, отмены вызова, проверки завершения вызова, проверки наличия каких-либо исключений во время обработки и проверки отмены вызова.

Получение окончательного результата из вызова асинхронного метода

Клиент может получить результат, используя один из методов Future<V>.get. Если обработка не была завершена сессионным компонентом, обрабатывающим вызов, то вызов одного из методов get приведёт к тому, что клиент остановит выполнение до завершения вызова. Используйте метод Future<V>.isDone, чтобы определить, завершена ли обработка перед вызовом одного из методов get.

Метод get() возвращает результат в виде типа, указанного в значении типа объекта Future<V>. Например, вызов Future<String>.get() вернёт объект String. Если вызов метода был отменён, вызовы get() приводят к генерированию java.util.concurrent.CancellationException. Если в результате вызова во время обработки сессионным компонентом возникла исключительная ситуация, вызовы get() приводят к выбрасыванию java.util.concurrent.ExecutionException. Причину ExecutionException можно узнать, вызвав метод ExecutionException.getCause.

Метод get(long timeout, java.util.concurrent.TimeUnit unit) похож на метод get(), но позволяет клиенту установить значение тайм-аута. Если превышено значение времени ожидания, генерируется java.util.concurrent.TimeoutException. См. Javadoc для класса TimeUnit для доступных единиц времени, чтобы указать значение времени ожидания.

Отмена асинхронного вызова метода

Вызовите метод cancel(boolean mayInterruptIfRunning) в объекте Future<V>, чтобы попытаться отменить вызов метода. Метод cancel возвращает true, если отмена была успешной, и false, если вызов метода не может быть отменён.

Если вызов нельзя отменить, параметр mayInterruptIfRunning используется для предупреждения объекта сессионного компонента, на котором выполняется вызов метода, о том, что клиент попытался отменить вызов. Если для mayInterruptIfRunning установлено значение true, вызовы SessionContext.wasCancelled объектом сессионного компонента возвращают true. Если mayInterruptIfRunning установить false, вызовы SessionContext.wasCancelled объектом сессионного компонента вернут false.

Метод Future<V>.isCancelled используется для проверки отмены вызова метода перед завершением вызова асинхронного метода путём вызова Future<V>.cancel. Метод isCancelled возвращает true, если вызов был отменён.

Проверка состояния вызова асинхронного метода

Метод Future<V>.isDone возвращает true, если объект сессионного компонента завершил обработку вызова метода. Метод isDone возвращает true, если асинхронный вызов метода завершился нормально, был отменён или привёл к исключению. То есть isDone указывает только то, завершил ли сессионный компонент обработку вызова.


Назад Вперёд Содержание
Логотип Oracle  Copyright © 2017, Oracle и/или её дочерних компаний. Все права защищены. Версия перевода 1.0.5 (Java EE Tutorial — русскоязычная версия)