[英]Thread local behaviour in spring boot
众所周知,Tomcat大约有200个线程,而Jetty在它们各自的线程池中都有一些默认计数线程。 因此,如果我们为每个请求在ThreadLocal
设置某些内容,它将在线程中存在一生,还是在每次请求后Tomcat清除ThreadLocal
。
如果我们在过滤器的userContext中设置某些内容,是否需要在每次过滤器退出时将其清除?
还是如果我们没有线程池配置,Web服务器是否每次都会创建一个新线程?
public static final ThreadLocal<UserContextDto> userContext = new ThreadLocal<>();
不会,Tomcat不会清除您的代码创建的ThreadLocals,这意味着它们将保留并可能污染后续请求。
因此,无论何时创建一个,请确保在同一请求或其他退出之前将其清除。
还应注意,后续请求(即使使用相同的URL)也可以在完全不同的线程中执行,因此ThreadLocals不是一种用于在请求之间保存状态的机制。 为此,可以使用像SessionBeans这样的东西。
如果您将某个内容放到了不是100%处于您控制之下的Thread的ThreadLocal中(即从其他代码中调用您的内容,例如HTTP请求),则需要在离开代码之前清除所有设置。
try
/ finally
结构是实现此目的的好方法。
线程池无法为您完成此操作,因为Java API没有提供清除线程的ThreadLocal
变量的方法。 (可以说这是Java API的缺点)
如果不这样做,则存在内存泄漏的风险,尽管如果存在线程泄漏,则受线程池的大小限制。
一旦将相同的线程再次分配给了解ThreadLocal
的代码,如果不删除它,您将看到上一个请求中的旧值。 依靠它是不好的。 它可能导致难以跟踪的错误,安全漏洞等。
是的,您需要清除ThreadLocal。 Tomcat不会清除ThreadLocals。
不,不是每次都创建新线程。 来自池的线程用于处理请求,并在请求完成后返回到池。
这不仅适用于Tomcat,还适用于Jetty和Undertow。 就资源和时间而言,为每个请求创建线程都是昂贵的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.