2015-07-23 3 views
4

Имея использование setAttribute() и getAttribute(String) в javax.servlet.ServletContext, я не могу найти информацию о предполагаемом поведении с одновременным доступом. Однако эти операции могут быть вызваны разными потоками.Является ли javax.servlet.ServletContext set/getAttribute потоком безопасным?

В servlet specification 3.0 состояния:

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

Однако информации о параллельных поведениях этих операций нет. Взгляд в source code Apache Tomcat показывает, что он реализован как ConcurrentHashMap, что делает его эффективно потокобезопасным.

Мой вопрос в том, должен ли я всегда рассматривать эти операции как небезопасные и иметь приложение, обрабатывающее синхронизацию, или есть ли какая-то информация, которую мне не хватает?

+1

http://stackoverflow.com/questions/20190070/thread-safety-of-servletcontext-objects –

ответ

5

Вы можете смело предположить, что вы можете вызвать getAttribute и setAttribute, не синхронизируясь ни на что, но вы должны сделать объекты, которые вы храните там threadafe (самый простой способ хранить вещи, которые являются неизменяемыми). Вопрос, связанный в комментариях, заключается в сохранении изменяемого объекта в servletContext, и в этом случае потоки, использующие его, должны сначала получить его блокировку (что объясняет the accepted answer).

Не требуется уточнение требований. Это описано в Java Параллелизм на практике, раздел 4.5.1 Интерпретация Смутное Документация:

Вы собираетесь должны угадать. Один из способов улучшить качество вашей догадки - интерпретировать спецификацию с точки зрения того, кто ее реализует (например, поставщик контейнера или базы данных), в отличие от того, кто просто ее использует. Сервлеты всегда вызываются из потока, управляемого контейнером, и можно с уверенностью предположить, что если есть более одного такого потока, контейнер знает об этом. Контейнер сервлета предоставляет определенные объекты, которые обеспечивают обслуживание нескольких сервлетов, таких как HttpSession или ServletContext. Таким образом, контейнер сервлетов должен ожидать одновременного доступа к этим объектам, поскольку он создал несколько потоков и вызвал из них такие методы, как Servlet.service, из которых можно было бы разумно ожидать доступа к ServletContext.

Поскольку невозможно представить однопоточный контекст, в котором эти объекты были бы полезны, следует предположить, что они были созданы в потоковом режиме, хотя спецификация явно не требует этого. Кроме того, если им требуется блокировка на стороне клиента, на какой блокировке должен быть синхронизирован код клиента? Документация не говорит, и это кажется абсурдным догадываться. Это «разумное предположение» дополнительно подкрепляется примерами в спецификациях и официальными учебными пособиями, в которых показано, как получить доступ к ServletContext или HttpSession и не использовать какую-либо клиентскую синхронизацию.

С другой стороны, объекты, помещенные в ServletContext или HttpSession с помощью setAttribute, принадлежат веб-приложению, а не контейнеру сервлета. Спецификация сервлета не предполагает какого-либо механизма для координации параллельного доступа к общим атрибутам. Поэтому атрибуты, хранящиеся в контейнере от имени веб-приложения, должны быть потокобезопасными или эффективно неизменными. Если весь контейнер был сохранен этими атрибутами от имени веб-приложения, другим вариантом будет гарантировать, что они будут последовательно защищены блокировкой при доступе из кода приложения сервлета.Но поскольку контейнер может захотеть сериализовать объекты в HttpSession для целей репликации или пассивации, и контейнер сервлета не может знать ваш протокол блокировки, вы должны сделать их потокобезопасными.

+0

Вы знаете, если «Java Параллелизм на практике» доступен в PDF версии для свободного скачивания? – hagrawal

+0

@hagrawal: Я не знаю. некоторые из них находятся на https://books.google.com/books?id=EK43StEVfJIC, но части опущены. –

+0

Хорошо. Спасибо. Если вы не возражаете, если у вас есть версия в формате PDF и вы можете поделиться со мной, тогда я был бы очень обязан. – hagrawal

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