2015-10-22 2 views
2

Рассмотрим алгоритм:Является ли HttpSessionAttributeListener обработанным async?

  1. новый атрибут добавляется к сеансу session.setAttribute("myObject", new Object);
  2. HttpSessionAttributeListener#attributeAdded вызывается
  3. код после session.setAttribute

HttpSessionAttributeListener#attributeAdded ли вызывает блок session.setAttribute или слушателя код асинхр?

ответ

3

Слушатель вызывается в той же теме, что и set|get|removeAttribute().

Итак, единственное условие гонки может возникнуть, когда setAttribute() вызывается в другом потоке. Учитывая, что средний контейнер сервлета использует single thread per HTTP connection (и, следовательно, не обязательно для HTTP-запроса, когда HTTP 1.1 keep-alive включен), то это условие гонки может возникнуть, когда enduser порождает два полностью отдельных экземпляра браузера (а не окна/вкладки) и копирует сеанс cookie от одного к другому, а затем одновременно запускает запрос от обоих клиентов на этом сеансе, запускающий метод setAttribute() на сервере.

Это, однако, не обычный случай реального мира. Более того, контейнер сам по себе будет беспокоиться о безопасности потоков, связанных с экземпляром HttpSession. Это указано в главе 7.7.1 из Servlet specification (курсив мой):

7.7.1 Проблемы многопоточности

Несколько сервлеты исполняющие запрос темы может иметь активный доступ к тому же объекту сессии одновременно. Контейнер должен гарантировать, что манипуляции с внутренними структурами данных, представляющими атрибуты сеанса, выполняются в потоке . Разработчик несет ответственность за поточный безопасный доступ к объектам атрибута . Это защитит коллекцию атрибутов внутри объекта HttpSession от одновременного доступа, исключая возможность приложения , чтобы привести к сбою этой коллекции.

Таким образом, ваша единственная забота - это третья безопасность самого атрибута. Например. если это ArrayList, и вы беспокоитесь о его безопасности потоков, вы, вероятно, захотите обернуть его в Collections#synchronizedList().

1

СИНХРОНИЧЕСКИЙ ПРОЦЕСС. Я просто сделал одну пробную программу.

JSP код:

<% 
session.setAttribute("ID","12324"); 
session.setAttribute("ID2","656565"); 
%> 

Слушатель Код attributeAdded() Метод:

String attributeName = event.getName(); 
     Object attributeValue = event.getValue(); 
     System.out.println("Attribute added : " + attributeName + " : " + attributeValue); 
     try { 
      Thread.sleep(10000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out.println("After Sleep : "+attributeName); 

Выход:

Attribute added : ID : 12324 
After Sleep : ID 
Attribute added : ID2 : 656565 
After Sleep : ID2 

Итак, вы можете видеть, что только после печати «После сна» для первого идентификатора он собирается добавить второй идентификатор в сеансе

Смежные вопросы