3

在典型的 Web 应用程序中,当请求进入时,过滤器会在 http 会话中查找 Context 对象。如果不存在,它会创建 Context 对象并将其存储在 http 会话中。此外,这个 Context 对象也存储在 ThreadLocal 对象中。沿路径的 Servlet 从 ThreadLocal 检索此 Context 对象并对其进行修改。当返回响应时,过滤器现在将 ThreadLocal 中的 Context 对象清空。那么当用户发出另一个请求时,他能看到修改后的 Context 对象吗?

谢谢夸迪尔

4

4 回答 4

3

不,如果您将其设为空(或更好地调用threadLocal.remove()),则该值将丢失。

如果您不这样做,则分配相同线程的某些下一个请求可能会看到它(servlet 容器使用线程池)。但这是线程池的一个不良副作用——你应该总是清理你的线程局部变量。(见这里

于 2011-09-05T15:27:23.343 回答
3

是的,用户将看到 Context 对象,因为对它的引用存储在 HttpSession 中。即使 ThreadLocal 中的引用为空,它仍然会在第二次请求期间在会话中找到。

编辑:在ThreadLocal 的 OpenJDK 源代码中(从第 410 行开始),您可以看到 ThreadLocal 的 set 和 remove 方法之间的区别。调用 set(null) 将使 ThreadLocalMap 条目保留为空值,而 remove() 将完全删除它。它不会对您的问题产生影响,会话中仍然会引用您的 Context 对象。

When I first read your question title I interpreted it differently because there was no mention of the HttpSession or clearing the ThreadLocal. Maybe this confused some of the responders. It sounded like you wanted to know if a ThreadLocal variable set in the first request (and not cleared) would still be accessible in the second request. I think the answer is that this depends on how your webserver handles threads. If there is a threadpool of 10 threads that are randomly reused you should have a 10% chance of finding the same ThreadLocal variable in the second request.

于 2011-09-05T16:24:36.813 回答
1

不 - 除非您使用线程池,否则它不会对下一个请求可见。但是不要让它为空——最好在线程本地实例上调用 remove() ——否则你可能会导致内存泄漏..

于 2011-09-05T16:24:06.670 回答
0

这取决于上下文。会话和应用程序上下文被显式恢复,而请求上下文和其他 ThreadLocals 可以绝对不依赖于在请求之间持续存在,因为同一个线程可以(并且通常会)处理来自完全不同用户的请求。我相信一些(如果不是全部)Web 容器故意删除所有 ThreadLocals 以避免用户意外共享数据。

于 2011-09-05T15:27:55.320 回答