Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用ThreadLocal作为数据上下文是一个好主意吗?_Java_Thread Local - Fatal编程技术网

Java 使用ThreadLocal作为数据上下文是一个好主意吗?

Java 使用ThreadLocal作为数据上下文是一个好主意吗?,java,thread-local,Java,Thread Local,在web应用程序中使用ThreadLocal作为数据上下文是一个好主意吗?这就是它的用途。但要注意删除上下文末尾的ThreadLocal,否则可能会导致内存泄漏,或者至少会将未使用的数据保留太长时间 ThreadLocals也非常快,您可以将其视为一个HashMap,它总是使用Thread.getCurrentThread()进行查询,这取决于数据的范围。ThreadLocal将特定于请求线程,而不是特定于用户会话(每个请求可能使用不同的请求处理线程)。因此,在请求处理完成时删除数据是很重要的(

在web应用程序中使用ThreadLocal作为数据上下文是一个好主意吗?

这就是它的用途。但要注意删除上下文末尾的ThreadLocal,否则可能会导致内存泄漏,或者至少会将未使用的数据保留太长时间


ThreadLocals也非常快,您可以将其视为一个
HashMap
,它总是使用
Thread.getCurrentThread()

进行查询,这取决于数据的范围。ThreadLocal将特定于请求线程,而不是特定于用户会话(每个请求可能使用不同的请求处理线程)。因此,在请求处理完成时删除数据是很重要的(这样,当同一个线程服务于其他用户的请求时,数据不会溢出到其他用户的会话中)。

如果您使用单个线程完成请求/响应对,那么根据我的经验,它工作得很好。然而,随着ajax和高性能容器的兴起,“事件驱动”webapps正在流行起来。这些事件驱动模型允许请求线程返回到它们的线程池,例如在I/O事件期间,这样线程就不会在等待外部服务调用返回时被占用。因此,单个逻辑请求可能由多个不同的线程提供服务。事件驱动的体系结构,再加上服务器端的NIO,可以大大提高吞吐量

话虽如此,如果您的应用程序没有这种体系结构,我认为这是合理的


如果您不熟悉此模型,请查看Tomcat6的“comet”和Jetty6的延续。这些是特定于供应商的异步I/O实现,有待正式的Servlet3.0支持。注意,Tomcat 7现在声称完全符合3.0。多线程程序中的ThreadLocal与非线程程序中的static/global非常相似。也就是说,使用
ThreadLocal
是一种令人憎恶的行为。

一般来说,我会说不。使用框架可以为您做到这一点

在web应用程序的web层中,使用会话上下文(或其他顶层框架特定上下文)存储请求范围内的数据和状态

当然,如果引入业务层,它不应该依赖于特定的web上下文
spring
JavaEE
提供了作为上下文的安全、事务和持久性解决方案


如果你用手触摸它,你应该非常小心;它会导致清理问题、内存泄漏和奇怪的bug…

为什么不使用框架提供的SessionContext?@Marcos,你是说SessionContext是由Java提供的吗?很抱歉,我不知道你指的是哪个框架……我想他指的是HttpSession和/或ServletContext(应用程序范围)。@Marcos:我想你指的是
javax.ejb.SessionContext
。如果应用程序不使用EnterpriseJavaBeans怎么办?
SessionContext
是非常不同的,特别是它不限于单个线程(考虑AJAX)。在某些情况下,它是需要的,而在另一些情况下,
RequestContext
更合适。不,这是一种在函数调用层次结构中深入传递上下文信息的好方法,而不必使用参数。@Daniel Yeah,与单线程程序中的静态/全局程序完全相同。
ThreadLocal
如果您正在运行自己的会话处理,则是一个不错的选择。大多数web框架都会为您这样做,并且可能会提供更大的灵活性(比如切换到基于NIO的工作线程,其中会话在线程之间切换)。那么它将是
HashMap
,但它只是
Thread
对象中的一个内部
Map
。它实际上不必是“事件驱动的”。如果线程空闲(等待IO),WebSphere7+将重用线程,然后您可以让一个线程处理两个不同的请求。我在两个请求之间的工作被“多路复用”时看到了这一点。如果使用threadlocals,这将导致一个非常丑陋的bug。