簡體   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