使用 ThreadLocal 作为数据上下文是个好主意吗?
使用 ThreadLocal 作为 Web 应用程序中数据的上下文是个好主意吗?
Is it a good idea to use ThreadLocal as a context for data in web application?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这就是它的目的。但请注意删除上下文末尾的 ThreadLocal,否则可能会出现内存泄漏,或者至少会保留未使用的数据太长时间。
ThreadLocals 也非常快,你可以把它想象成一个
HashMap
,总是用Thread.getCurrentThread()
来查询它。That's what it was made for. But take care to remove the ThreadLocal on the end of the context, else you might run in memory leaks, or at least hold unused data for too long.
ThreadLocals are also very fast, you can think of it as a
HashMap<Thread,Object>
, which is always queried withThread.getCurrentThread()
.这取决于数据的范围。 ThreadLocal 将特定于请求线程,而不特定于用户会话(每个请求,可能会使用不同的请求处理线程)。因此,在请求处理完成时删除数据非常重要(这样当同一线程处理其请求时,数据就不会渗透到其他用户的会话中)。
That depends on the scope of the data. The ThreadLocal will be specific to the request thread, not specific to the user's session (each request, a different request processing thread may be used). Hence it will be important to remove the data as the request processing is completing (so that it doesn't bleed over into some other user's session when that same thread services their request).
如果您使用单个线程完成请求/响应对,那么根据我的经验,它工作得很好。然而,随着 ajax 和高性能容器的兴起,“事件驱动”的 Web 应用程序开始流行。这些事件驱动模型允许请求线程返回到它们的线程池,例如在I/O事件期间,使得线程不会被占用以等待外部服务调用返回。因此,单个逻辑请求可能由多个不同的线程提供服务。事件驱动架构与服务器端的 NIO 相结合可以显着提高吞吐量。
话虽如此,如果您的应用程序没有这种架构,这对我来说似乎是合理的。
如果你不熟悉这个模型,请看一下 Tomcat 6 的“comet”和 Jetty 6 的 Continuations。这些是异步 I/O 的供应商特定实现,有待官方 Servlet 3.0 支持。请注意,Tomcat 7 声称现在完全兼容 3.0。
If you are completing a request/response pair with a single thread, then it works fine in my experience. However, "event driven" webapps are coming into vogue with the rise of ajax and high performance containers. These event driven models allow for a request thread to be returned to their thread pool, e.g. during I/O events, so that the thread is not occupied waiting for an external service call to return. As a result, a single logical request may be serviced by multiple different threads. Event driven architecture, coupled with NIO on the server side can yield highly improved throughput.
With that said, if your application doesn't have this architecture, it seems reasonable to me.
If you're not familiar with this model, take a look at Tomcat 6's "comet" and Jetty 6's Continuations. These are vendor-specific implementations of asynchronous I/O pending official Servlet 3.0 support. Note that Tomcat 7 claims to be fully 3.0 compliant now.
多线程程序中的 ThreadLocal 与非线程程序中的静态/全局非常相似。也就是说,使用
ThreadLocal
是一种令人厌恶的行为。ThreadLocal
in a multithreaded program is much the same as a static/global in a non-threaded program. That is to say, use ofThreadLocal
is an abomination.一般来说我会说不。使用框架来为您做到这一点。
在 Web 应用程序的 Web 层中,使用会话上下文(或其他顶层框架特定上下文)来存储请求范围内的数据和状态。
如果您引入业务层,它当然不应该依赖于特定的 Web 上下文。
spring
和Java EE
提供了作为上下文的安全性、事务和持久性解决方案。如果你手动触摸它,你应该非常小心;它可能会导致清理问题、内存泄漏和奇怪的错误......
In general I would say no. Use frameworks to do that for you.
In the web-tier of a web application use the session context (or other on top framework specific contexts) to store data and state over request scope.
If you introduce a business layer it should not be dependent on a specific web-context of course.
spring
andJava EE
provide solutions for security, transactions and persistence as a context.If you touch this manually you should be really careful; it can lead to cleanup problems, memory leaks, and strange bugs...