Spring Boot 中的线程本地行为

我们知道 Tomcat 有大约 200 个线程,而 Jetty 在各自的线程池中有一些默认计数的线程。因此,如果我们在ThreadLocal每个请求中设置一些内容,它会在线程中终生存在,还是 TomcatThreadLocal在每个请求后清除它。

如果我们在过滤器中的 userContext 中设置某些内容,是否需要在每次过滤器退出时清除它?

或者如果我们没有线程池配置,Web 服务器是否每次都会创建一个新线程?

public static final ThreadLocal<UserContextDto> userContext = new ThreadLocal<>();


萧十郎
浏览 94回答 3
3回答

慕容708150

是的,你需要清除ThreadLocal。Tomcat 不会清除 ThreadLocals。不,并不是每次都会创建新线程。池中的线程用于服务请求,并在请求完成后返回池。这不仅适用于 Tomcat,也适用于 Jetty 和 Undertow。为每个请求创建线程在资源和时间方面都是昂贵的。

HUX布斯

不,Tomcat 不会清除您的代码创建的 ThreadLocals,这意味着它们将保留并可能污染后续请求。因此,每当您创建一个请求时,请确保在同一请求或任何其他请求存在之前将其清除。还应该注意的是,后续请求 - 即使使用相同的 URL - 也可能在完全不同的线程中执行,因此 ThreadLocal 不是一种在请求之间保存状态的机制。为此,可以使用 SessionBeans 之类的东西。

素胚勾勒不出你

如果您在不是 100% 控制的线程中的 ThreadLocal 中放置了某些内容(即从其他代码调用您的线程,例如 HTTP 请求),则需要在离开代码之前清除您设置的任何内容。A&nbsp;try/finally结构是一个很好的方法。线程池无法为您做到这一点,因为 Java API 不提供清除线程ThreadLocal变量的方法。(这可以说是Java API的一个缺点)不这样做会有内存泄漏的风险,尽管它受到线程池大小的限制(如果有的话)。一旦同一线程再次分配给了解 的代码ThreadLocal,如果您没有删除它,您将看到上一个请求的旧值。依赖于此是不好的。它可能会导致难以追踪的错误、安全漏洞等。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java