繁体   English   中英

Spring Boot中的线程本地行为

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM