2011-01-26 2 views
3

Я столкнулся с ситуацией, когда я использую статическую переменную ThreadLocal для хранения компонента, который содержит различные значения показателей из разных классов в течение жизненного цикла запроса. В фильтре я создаю компонент и устанавливаю его в локальной переменной потока и удаляю его из локальной переменной потока в том же фильтре после обработки запроса. Я запутался в том, что bean, содержащий значения из других запросов! Единственным объяснением этого является поток, который совместно используется для обработки нескольких запросов одновременно. Итак, вопрос в названии.Является ли поток гарантированным для всего запроса обработанным сервлетом?

ответ

6

Хотя один поток, как правило, обрабатывает один запрос (говоря о tomcat, наверняка), поток может обрабатывать несколько запросов с течением времени, но не до конца существующего запроса, если только не использовать include/forward alikes.

Я бы очень рекомендовал использовать атрибут (setAttribute()) указанного запроса w/your bean и использовать его для профилирования. Если вы не можете предоставить запрос различным методам ... ну, вы застряли с ThreadLocal [это не так плохое решение].

В качестве альтернативы вы можете публиковать код, как вы устанавливаете/удаляете threadLocal bean.

Имейте в виду, что вам нужно управлять каким-либо компонентом этого компонента (он не будет доступен вне запроса).

Редактировать: забыл спросить: используете ли вы try/finally call doFilter (...)?

код должен быть таким

installBean(); 
try{ 
    chain.doFilter(req, resp); 
}finally{ 
Bean b = deinstallBean(); 
useTheMetrics(b); 
//potentially, process exception, etc 
} 
+0

Да, «наконец» сделал магию. Как сказал Майкл и Эриксон, в одном случае исключение во время выполнения не удаляло компонент. Спасибо. – Murali

+0

Правило большого пальца (или мораль истории): Если вы изменяете ЛЮБОЕ глобальное состояние и собираетесь его отменить. Используйте try/finally, на самом деле используйте try/finally, необходимо любое удаление/закрытие/удаление (или неявный откат), это почти не требует каких-либо штрафных санкций (учтите это бесплатно: D) – bestsss

2

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

1

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

Используйте блок finally, чтобы очистить (установить на null) ThreadLocal в фильтр после обработки остальной цепи. Это предотвратит совпадение данных из предыдущих запросов с текущим запросом.

+0

Почему безопасно предположить, что ? есть ли стандарт, в котором говорится, что один поток будет обрабатывать все фильтры для сервлета и самого сервлета? не было ли что-то о кластерном сервере приложений, так что куча JVMs вместе работает как сервер приложений? – necromancer