threadlocals 变量对拥有变量的 servlet 发出的所有请求都是全局的吗?
我正在为服务器使用树脂。
谢谢你的遮阳篷。
我想我可以让自己更清楚。
具体案例:
我想要:
- 当请求开始执行时初始化一个静态变量。
- 能够以线程安全的方式在从 servlet 调用的方法的进一步执行中查询变量的值,直到请求结束执行
threadlocals 变量对拥有变量的 servlet 发出的所有请求都是全局的吗?
我正在为服务器使用树脂。
谢谢你的遮阳篷。
我想我可以让自己更清楚。
具体案例:
我想要:
简短的回答:是的。
再长一点:这就是 Spring 发挥它的魔力的方式。请参阅RequestContextHolder(通过 DocJar)。
不过需要小心——您必须知道何时使 ThreadLocal 无效、如何推迟到其他线程以及如何(不)与非线程本地上下文纠缠在一起。
或者你可以只使用弹簧......
我认为它们对于仅使用该特定线程发出的所有请求都是全局的。其他线程获取线程本地数据的其他副本。这是线程本地存储的关键点: http ://en.wikipedia.org/wiki/Thread-local_storage#Java 。
除非您在 servlet 配置中选中适当的选项,否则 servlet 容器将使用您的 servlet 和多个线程来并行处理请求。如此有效地,您将为为客户端提供服务的每个线程拥有单独的数据。
如果您的 WebApplication 不是分布式的(在多个 Java 虚拟机上运行),您可以使用该ServletContext
对象在请求和线程之间存储共享数据(然后确保进行适当的锁定)。
正如 Adiel 所说,正确的做法可能是使用请求上下文(即 HttpServletRequest),而不是创建 ThreadLocal。虽然这里当然可以使用 ThreadLocal,但是如果你这样做,你必须小心清理你的线程,因为否则下一个获取线程的请求将看到与前一个请求关联的值。(当第一个请求用线程完成时,线程将返回到池中,因此下一个请求将看到它。)当请求上下文正是为此目的而存在时,没有理由必须管理这种事情。
如果您使用 Servlet 3.0 可暂停请求(或 Jetty Continuations),使用 ThreadLocal 存储请求范围信息可能会中断使用这些 API 的多个线程处理单个请求。
Threadlocal 变量总是被定义为可以全局访问,因为关键是要在可以在任何地方访问的系统周围透明地传递信息。变量的值绑定到设置它的线程,因此即使变量是全局的,它也可以根据访问它的线程具有不同的值。
一个简单的例子是当在 servlet 中接收到请求时,将用户身份字符串分配给线程局部变量中的线程。沿着该请求的处理链的任何地方(假设它在同一个 VM 的同一个线程上),都可以通过访问这个全局变量来检索身份。在处理请求时删除此值也很重要,因为线程将被放回线程池中。