В Java, когда объекты ThreadLocal будут изменены, сохранятся ли изменения в следующем запросе? - PullRequest
3 голосов
/ 05 сентября 2011

В типичном веб-приложении при поступлении запроса фильтр ищет объект Context в сеансе http.Если он не существует, он создает объект Context и сохраняет его в сеансе http.Кроме того, этот объект Context также хранится в объекте ThreadLocal.Сервлет по пути извлекает этот объект Context из ThreadLocal и модифицирует его.Когда ответ возвращается, фильтр теперь обнуляет объект Context в ThreadLocal.Поэтому, когда пользователь делает еще один запрос, сможет ли он увидеть измененный объект Context?

Спасибо, Quadir

Ответы [ 4 ]

3 голосов
/ 05 сентября 2011

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

РЕДАКТИРОВАТЬ: В исходном коде OpenJDK ThreadLocal (из строки 410) вы можетеувидеть разницу между setLoid и методами удаления.Вызов set (null) оставит запись ThreadLocalMap на месте с нулевым значением, тогда как remove () удалит ее полностью.Это не повлияет на ваш вопрос, в сеансе все равно будет ссылка на ваш объект Context.

Когда я впервые прочитал заголовок вашего вопроса, я интерпретировал его по-другому, потому что не было упоминанияHttpSession или очистка ThreadLocal.Может быть, это смутило некоторых респондентов.Похоже, вы хотели знать, будет ли переменная ThreadLocal, установленная в первом запросе (и не очищена), по-прежнему доступна во втором запросе.Я думаю, что ответ заключается в том, что это зависит от того, как ваш веб-сервер обрабатывает потоки.Если есть пул потоков из 10 потоков, которые используются случайным образом, у вас будет 10% шанс найти ту же переменную ThreadLocal во втором запросе.

3 голосов
/ 05 сентября 2011

Нет.Если вы обнулите его (или лучше позвоните threadLocal.remove()), значение будет потеряно.

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

1 голос
/ 05 сентября 2011

Нет - он не будет виден для следующего запроса, если вы не используете пул потоков.Но вместо того, чтобы делать его нулевым - лучше вызывать remove () в локальном экземпляре потока - в противном случае вы можете привести к утечкам памяти ..

0 голосов
/ 05 сентября 2011

Это зависит от контекста. Контексты сеанса и приложения явно восстанавливаются, в то время как на контексты запросов и другие ThreadLocals нельзя полностью полагаться на то, что они сохраняются между запросами, поскольку один и тот же поток может (и обычно будет) обрабатывать запрос от совершенно другого пользователя. Я считаю, что некоторые (если не все) веб-контейнеры намеренно удаляют все ThreadLocals, чтобы избежать случайного совместного использования данных пользователями.

...