Изучаем Java EE 7 - [120]

Шрифт
Интервал

>@DependsOn("business.jar#CountryCodeEJB")

>@Singleton

>public class CacheEJB {…}

Следует отметить, что ссылка такого рода влечет зависимость кода от деталей упаковки (которыми в данном случае являются имена файлов модулей).

Конкурентный доступ

Как вы уже понимаете, имеется единственный экземпляр одиночного сессионного EJB-компонента, который совместно используется множественными клиентами. Таким образом, конкурентный доступ для клиентов разрешается, при этом им можно управлять с помощью аннотации @ConcurrencyManagement на основе двух разных подходов.

• Конкурентный доступ, управляемый контейнером (CMC), — контейнер управляет конкурентным доступом к экземпляру EJB-компонента, исходя из метаданных (аннотации или XML-эквивалента).

• Конкурентный доступ, управляемый EJB-компонентом (BMC), — контейнер разрешает полный конкурентный доступ и возлагает ответственность за синхронизацию на EJB-компонент.

Если не указать, на основе какого подхода должно осуществляться управление доступом, то по умолчанию будет использоваться конкурентный доступ, управляемый контейнером. В случае с одиночным EJB-компонентом может предусматриваться использование либо одного, либо другого вида доступа, но не обоих сразу. Как вы увидите в последующих разделах, аннотацию @AccessTimeout можно применять для запрета конкурентного доступа (иначе говоря, если клиент вызовет бизнес-метод, который уже используется другим клиентом, то конкурентный вызов приведет к генерированию исключения ConcurrentAccessException).

Конкурентный доступ, управляемый контейнером

При таком доступе (он является подходом по умолчанию) контейнер отвечает за управление конкурентным доступом к экземпляру одиночного EJB-компонента. Тогда вы сможете использовать аннотацию @Lock для указания того, как контейнер должен управлять доступом при вызове метода клиентом. Эта аннотация может принимать значение READ (общая блокировка) или WRITE (эксклюзивная блокировка).

• @Lock(LockType.WRITE) — метод, ассоциированный с эксклюзивной блокировкой, не позволит выполнять конкурентные вызовы до тех пор, пока не завершится обработка, осуществляемая этим методом. Например, если клиент C1 вызовет метод с эксклюзивной блокировкой, то клиент C2 не сможет вызвать этот метод, пока клиент C1 не закончит.

• @Lock(LockType.READ) — метод, ассоциированный с общей блокировкой, позволит выполнять любое количество других конкурентных вызовов для экземпляра EJB-компонента. Например, два клиента — C1 и C2 — смогут одновременно получить доступ к методу с общей блокировкой.

Аннотацией @Lock можно снабдить классы, методы либо и те и другие сразу. Если снабдить ею класс, то это будет означать, что она распространяется на все методы. Если вы не укажете атрибут блокировки конкурентного доступа, то по умолчанию будет предполагаться @Lock(WRITE). В коде, приведенном в листинге 7.11, показан CacheEJB с блокировкой WRITE в классе EJB-компонента. Это подразумевает, что для всех методов будет иметь место конкурентный доступ WRITE за исключением getFromCache(), по отношению к которому осуществляется переопределение с использованием READ.


Листинг 7.11. Одиночный сессионный EJB-компонент с конкурентным доступом, управляемым контейнером

>@Singleton

>@Lock(LockType.WRITE)

>@AccessTimeout(value = 20, unit = TimeUnit.SECONDS)

>public class CacheEJB {

>··private Map cache = new HashMap<>();

>··public void addToCache(Long id, Object object) {

>····if (!cache.containsKey(id))

>······cache.put(id, object);

>··}

>··public void removeFromCache(Long id) {

>····if (cache.containsKey(id))

>······cache.remove(id);

>··}

>··@Lock(LockType.READ)

>··public Object getFromCache(Long id) {

>····if (cache.containsKey(id))

>······return cache.get(id);

>····else

>······return null;

>··}

>}

В листинге 7.11 класс снабжен аннотацией @AccessTimeout. При блокировке конкурентного доступа можно указать время ожидания для отклонения запроса, если блокировка не будет применена в течение определенного времени. Если вызов addToCache() станет блокироваться более 20 секунд, то для клиента будет сгенерировано исключение ConcurrentAccessTimeoutException.

Конкурентный доступ, управляемый EJB-компонентом

При использовании такого подхода, как конкурентный доступ, управляемый EJB-компонентом, контейнер разрешает полный конкурентный доступ к экземпляру одиночного EJB-компонента. Тогда вы будете отвечать за защиту его состояния от ошибок синхронизации вследствие конкурентного доступа. В этом случае вам будет разрешено использовать Java-примитивы синхронизации, например synchronized и volatile. В коде, приведенном в листинге 7.12, показан CacheEJB с конкурентным доступом, управляемым EJB-компонентом (@ConcurrencyManagement(BEAN)), при этом для методов addToCache() и removeFromCache() используется ключевое слово synchronized.


Листинг 7.12. Одиночный сессионный EJB-компонент с конкурентным доступом, управляемым EJB-компонентом

>@Singleton

>@ConcurrencyManagement(ConcurrencyManagementType.BEAN)

>public class CacheEJB {

>··private Map cache = new HashMap<>();


>··public synchronized void addToCache(Long id, Object object) {


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.