2008-11-26 5 views
6

Являются ли переменными threadlocals глобальными для всех запросов, поступающих к сервлету, которому принадлежат переменные?threadlocal variables в сервлете

Я использую смолу для сервера.

Спасибо за тент.

Я думаю, что я могу сделать свое ясное яснее.

Конкретный случай:

Я хочу:

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

ответ

3

Я думаю, что они являются глобальными для всех запросов, сделанных с этим только конкретная тема. Другие потоки получают другие копии thread-local. Это ключевой момент для локального хранилища потоков: http://en.wikipedia.org/wiki/Thread-local_storage#Java.

Если вы не проверите соответствующий параметр в конфигурации сервлетов, контейнер сервлетов будет использовать ваш сервлет с несколькими потоками для параллельной обработки запросов. Таким образом, у вас будут отдельные данные для каждого потока, обслуживающего клиентов.

Если ваш WebApplication не распространяется (выполняется на нескольких виртуальных машинах Java), вы можете использовать объект ServletContext для хранения общих данных по запросам и потокам (обязательно выполните соответствующую блокировку).

+0

Действительно. В предыдущем проекте я сохранил билет пользователя в своем сеансе и создал фильтр для переноса билета из сеанса в локальный поток, чтобы убедиться, что пользовательское состояние аутентификации всегда доступно для потока, обрабатывающего запрос. – Julie 2008-11-26 19:47:25

0

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

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

2

Как и Adiel, подходящий способ сделать это, вероятно, использовать контекст запроса (то есть HttpServletRequest), а не создавать ThreadLocal. Хотя здесь возможно использовать ThreadLocal, вы должны быть осторожны, чтобы очистить свой поток, если вы это сделаете, поскольку в противном случае следующий запрос, который получает поток, увидит значение, связанное с предыдущим запросом. (Когда первый запрос выполняется с потоком, поток будет возвращаться в пул, и поэтому следующий запрос увидит его.) Нет причин для управления такими вещами, когда контекст запроса существует именно для этой цели.

+0

Вы также можете использовать фильтр сервлета для управления ThreadLocal, по крайней мере, создание/очистка будет в одном месте. – sehugg 2009-06-11 17:09:41

+1

-1 Есть определенно веская причина «управлять такой штукой», есть разница между передаваемым аргументом 1000 раз вокруг вашего приложения, по сравнению с просто одним статическим getter ;-) – peenut 2013-02-22 06:58:55

4

Короткий ответ: Да.
Немного длиннее: так Весна делает свою магию. См. RequestContextHolder (через DocJar).

Необходимо проявлять осторожность: вы должны знать, когда следует аннулировать ThreadLocal, как отложить до других потоков и как (не) запутаться в не-threadlocal контексте.

Или вы могли бы просто использовать Spring ...

1

Использование ThreadLocal для хранения запроса информации области видимости имеет потенциал, чтобы сломаться, если вы используете Servlet 3.0 суспендируемых запросов (или Jetty Продолжения) Использование нескольких потоков тех, API, обрабатывает один запрос.

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