java servlet 中的线程局部变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/321757/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
threadlocal variables in a servlet
提问by user2427
Are the threadlocals variables global to all the requests made to the servlet that owns the variables?
对于所有对拥有这些变量的 servlet 的请求,threadlocals 变量是否是全局的?
I am using resin for the server.
我正在为服务器使用树脂。
Thanks for awnser.
感谢 awnser。
I think I can make my self more clear.
我想我可以让我自己更清楚。
The specific Case:
具体案例:
I want to:
我想要:
- initialize a static variable when the request starts the execution.
- be able to query the value of the variable in the further executions of methods called from the servlet in a thread safety way until the request ends the execution
- 当请求开始执行时初始化一个静态变量。
- 能够以线程安全的方式在进一步执行从 servlet 调用的方法中查询变量的值,直到请求结束执行
回答by Ran Biron
Short answer: Yes.
A bit longer one: This is how Spring does its magic. See RequestContextHolder(via DocJar).
简短的回答:是的。
再长一点:这就是 Spring 发挥其魔力的方式。见RequestContextHolder(通过DocJar)。
Caution is needed though - you have to know when to invalidate the ThreadLocal, how to defer to other threads and how (not) to get tangled with a non-threadlocal context.
但是需要注意 - 您必须知道何时使 ThreadLocal 无效,如何推迟到其他线程以及如何(不)与非线程本地上下文纠缠在一起。
Or you could just use Spring...
或者你可以只使用 Spring ...
回答by Johannes Schaub - litb
I think they are global to all requests made with that specific thread only. Other threads get other copies of the thread-localdata. This is the key point of thread-local storage: http://en.wikipedia.org/wiki/Thread-local_storage#Java.
我认为它们仅适用于使用该特定线程发出的所有请求。其他线程获取线程本地数据的其他副本。这是线程本地存储的关键点:http: //en.wikipedia.org/wiki/Thread-local_storage#Java。
Unless you check the appropriate option in the servlets config, the servlet container will use your servlet with multiple threads to handle requests in parallel. So effectively you would have separate data for each thread that's up serving clients.
除非您在 servlets 配置中选中适当的选项,否则 servlet 容器将使用具有多个线程的 servlet 来并行处理请求。如此有效地,您将为为客户端提供服务的每个线程拥有单独的数据。
If your WebApplication isn't distributed (runs on multiple Java Virtual Machines), you can use the ServletContextobject to store shared data across requests and threads (be sure to do proper locking then).
如果您的 WebApplication 不是分布式的(在多个 Java 虚拟机上运行),您可以使用该ServletContext对象来存储跨请求和线程的共享数据(然后确保进行适当的锁定)。
回答by Johannes Schaub - litb
Like Adiel says, the proper way to do this is probably to use the request context (i.e. HttpServletRequest), not to create a ThreadLocal. While it's certainly possible to use a ThreadLocal here, you have to be careful to clean up your thread if you do that, since otherwise the next request that gets the thread will see the value associated with the previous request. (When the first request is done with the thread, the thread will go back into the pool and so the next request will see it.) No reason to have to manage that kind of thing when the request context exists for precisely this purpose.
正如 Adiel 所说,正确的方法可能是使用请求上下文(即 HttpServletRequest),而不是创建 ThreadLocal。虽然在这里当然可以使用 ThreadLocal,但如果这样做,您必须小心清理您的线程,否则获取线程的下一个请求将看到与前一个请求关联的值。(当该线程完成第一个请求时,该线程将返回到池中,因此下一个请求将看到它。)当请求上下文正是出于此目的而存在时,没有理由必须管理这种事情。
回答by Chris
Using ThreadLocal to store request scoped information has the potential to break if you use Servlet 3.0 Suspendable requests (or Jetty Continuations) Using those API's multiple threads process a single request.
如果您使用 Servlet 3.0 Suspendable requests(或 Jetty Continuations),则使用 ThreadLocal 存储请求范围的信息可能会中断。使用这些 API 的多个线程处理单个请求。
回答by Robin
Threadlocal variables are always defined to be accessed globally, since the point is to transparently pass information around a system that can be accessed anywhere. The value of the variable is bound to the thread on which it is set, so even though the variable is global, it can have different values depending on the thread from which it is accessed.
线程局部变量总是被定义为全局访问,因为重点是透明地传递可以在任何地方访问的系统周围的信息。变量的值绑定到设置它的线程,因此即使变量是全局的,它也可以根据访问它的线程具有不同的值。
A simple example would be to assign a user identity string to a thread in a thread local variable when the request is received in the servlet. Anywhere along the processing chain of that request (assuming it is on the same thread in the same VM), the identity can be retrieved by accessing this global variable. It would also be important to remove this value when the request is processed, since the thread will be put back in a thread pool.
一个简单的示例是在 servlet 中接收到请求时,将用户身份字符串分配给线程局部变量中的线程。在该请求的处理链中的任何地方(假设它在同一个 VM 中的同一个线程上),都可以通过访问这个全局变量来检索身份。在处理请求时删除此值也很重要,因为线程将放回线程池中。

