使用 ThreadLocal 作为 Web 应用程序中数据的上下文是个好主意吗?
5 回答
这就是它的目的。但是请注意删除上下文末尾的 ThreadLocal ,否则您可能会在内存泄漏中运行,或者至少将未使用的数据保存太久。
ThreadLocals 也非常快,你可以把它想象成一个HashMap<Thread,Object>
,它总是用 来查询Thread.getCurrentThread()
。
这取决于数据的范围。ThreadLocal 将特定于请求线程,而不特定于用户会话(每个请求,可能使用不同的请求处理线程)。因此,在请求处理完成时删除数据非常重要(这样当同一个线程为他们的请求提供服务时,它不会渗入其他用户的会话)。
如果您使用单个线程完成请求/响应对,那么根据我的经验,它可以正常工作。然而,随着 ajax 和高性能容器的兴起,“事件驱动”的 webapps 正在流行起来。这些事件驱动模型允许将请求线程返回到它们的线程池,例如在 I/O 事件期间,以便线程不会被占用等待外部服务调用返回。因此,单个逻辑请求可能由多个不同的线程提供服务。事件驱动架构,再加上服务器端的 NIO,可以大大提高吞吐量。
话虽如此,如果您的应用程序没有这种架构,对我来说这似乎是合理的。
如果您不熟悉此模型,请查看 Tomcat 6 的“彗星”和 Jetty 6 的 Continuations。这些是等待官方 Servlet 3.0 支持的异步 I/O 的供应商特定实现。请注意,Tomcat 7 现在声称完全兼容 3.0。
ThreadLocal
在多线程程序中与非线程程序中的静态/全局非常相似。也就是说,使用ThreadLocal
是可憎的。
一般来说,我会说不。使用框架为您做到这一点。
在 Web 应用程序的 Web 层中,使用会话上下文(或其他顶级框架特定上下文)来存储请求范围内的数据和状态。
如果您引入业务层,它当然不应该依赖于特定的 Web 上下文。spring
并Java EE
为作为上下文的安全性、事务和持久性提供解决方案。
如果您手动触摸它,您应该非常小心;它可能导致清理问题、内存泄漏和奇怪的错误......