Является ли потомок HttpSession безопасным, установлены/получаются операции с атрибутами потока атрибутов?

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

Кроме того, я читал в Интернете, что некоторые предлагают использовать:

synchronized(session) {
  session.setAttribute("abc", "abc");
}

Действительно ли это предложение?

Ответ 2

Servlet 2.5 spec:

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

Это безопасно:

// guaranteed by the spec to be safe
request.getSession().setAttribute("foo", 1);

Это безопасно не:

HttpSession session = request.getSession();
Integer n = (Integer) session.getAttribute("foo");
// not thread safe
// another thread might be have got stale value between get and set
session.setAttribute("foo", (n == null) ? 1 : n + 1);

Это не гарантировано:

// no guarantee that same instance will be returned,
// nor that session will lock on "this"
HttpSession session = request.getSession();
synchronized (session) {
  Integer n = (Integer) session.getAttribute("foo");
  session.setAttribute("foo", (n == null) ? 1 : n + 1);
}

Я видел, как этот последний подход защищен (в том числе и в J2EE-книгах), но он не гарантированно работает по спецификации Servlet. Вы можете использовать идентификатор сеанса для создания мьютекса, но должен быть лучший подход.

Ответ 3

Нет. И поскольку вы не хотите, чтобы один и тот же клиент (с сеансом) выполнял параллельные запросы, вы должны сериализовать эти запросы, например AbstractController в Spring MVC

Ответ 4

В некотором роде это зависит от дизайна вашего клиента.

У вас есть возможность в вашем веб-дизайне для одного клиента иметь несколько выдающихся одновременных запросов, используя тот же HTTP-сеанс? Это сложно сделать, если вы не связываете один сеанс HTTP с несколькими сокетами. (aka, AJAX). Короче говоря, данный клиентский HTTP-доступ будет однопоточным по отношению к серверу, что означает, что один сеанс эффективно защищен потоком.

Синхронизация ваших объектов сеанса сделает приложение более безопасным с будущими изменениями, которые заставят ваше веб-приложение иметь несколько одновременных запросов, поэтому это не плохая идея. В современных реализациях Java синхронизация не имеет больших затрат, которые ранее были связаны с ней, особенно когда синхронизация обычно не используется. Если ваше приложение использует AJAX, что подразумевает, что вы ожидаете несколько одновременных запросов на вашем веб-сервере во время полета, синхронизация является обязательной.

Ответ 5

Это не так, но в большинстве случаев ваши клиенты будут обращаться к ним только с помощью одного потока.

У разных клиентов будут разные потоки, и каждый из них будет иметь свою собственную сессию.

Как отмечает Эдди, в одной ситуации, когда вы можете столкнуться с двумя потоками, обращающимися к одному сеансу, два вызова ajax пытаются изменить один и тот же атрибут сеанса. В противном случае у вас не будет проблем.

Ответ 6

Сеанс не является потокобезопасным, и ни один из методов get not the set не гарантирован потоком. Как правило, в контейнере сервлетов вы должны предполагать, что он находится в многопоточной среде, и никакая предоставленная оснастка не безопасна.

Это также относится к объектам, которые вы храните в сеансе. Сам сеанс не будет манипулировать сохраненным объектом, но вы можете получить объект в другом потоке и попытаться манипулировать им. Это зависит от вас, чтобы проверить свой собственный код, чтобы узнать, возможны ли условия гонки.

Выведенный вами пример кода действителен, но проблема может существовать за пределами ограниченного объема вашего примера. Он гарантирует, что при настройке сеанса нет условий, но нет ничего, что мешает другому потоку переопределить набор. Если код в запросе зависит от неизменного значения, вы все равно можете быть в затруднении.