在Java中,当ThreadLocal对象被修改时,这些更改会在下一个请求中保留吗?



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

谢谢Quadir

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

编辑:在ThreadLocal的OpenJDK源代码中(从第410行开始),你可以看到ThreadLocal的set和remove方法之间的区别。调用set(null)将以空值保留ThreadLocalMap条目,而remove()将完全删除它。对于你的问题来说,这不会有什么不同,会话中仍然会有一个对Context对象的引用。

当我第一次读到你的问题标题时,我对它的解释不同,因为没有提到HttpSession或清除ThreadLocal。也许这让一些急救人员困惑了。听起来,您想知道在第一个请求中设置的ThreadLocal变量(未清除)是否仍然可以在第二个请求中访问。我认为答案是,这取决于你的web服务器如何处理线程。如果有一个包含10个随机重用线程的线程池,那么在第二个请求中应该有10%的机会找到相同的ThreadLocal变量。

No。如果您为null(或者最好调用threadLocal.remove()),该值将丢失。

如果不这样做,可能对分配给相同线程的下一个请求可见(servlet容器使用线程池)。但这是线程池的一个不良副作用——您应该始终清理线程局部。(见这里)

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

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

相关内容

最新更新