3 回答

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超4個(gè)贊
是的,你需要清除ThreadLocal。Tomcat 不會(huì)清除 ThreadLocals。
不,并不是每次都會(huì)創(chuàng)建新線程。池中的線程用于服務(wù)請(qǐng)求,并在請(qǐng)求完成后返回池。
這不僅適用于 Tomcat,也適用于 Jetty 和 Undertow。為每個(gè)請(qǐng)求創(chuàng)建線程在資源和時(shí)間方面都是昂貴的。

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超6個(gè)贊
不,Tomcat 不會(huì)清除您的代碼創(chuàng)建的 ThreadLocals,這意味著它們將保留并可能污染后續(xù)請(qǐng)求。
因此,每當(dāng)您創(chuàng)建一個(gè)請(qǐng)求時(shí),請(qǐng)確保在同一請(qǐng)求或任何其他請(qǐng)求存在之前將其清除。
還應(yīng)該注意的是,后續(xù)請(qǐng)求 - 即使使用相同的 URL - 也可能在完全不同的線程中執(zhí)行,因此 ThreadLocal 不是一種在請(qǐng)求之間保存狀態(tài)的機(jī)制。為此,可以使用 SessionBeans 之類的東西。

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超9個(gè)贊
如果您在不是 100% 控制的線程中的 ThreadLocal 中放置了某些內(nèi)容(即從其他代碼調(diào)用您的線程,例如 HTTP 請(qǐng)求),則需要在離開代碼之前清除您設(shè)置的任何內(nèi)容。
A try
/finally
結(jié)構(gòu)是一個(gè)很好的方法。
線程池?zé)o法為您做到這一點(diǎn),因?yàn)?Java API 不提供清除線程ThreadLocal
變量的方法。(這可以說是Java API的一個(gè)缺點(diǎn))
不這樣做會(huì)有內(nèi)存泄漏的風(fēng)險(xiǎn),盡管它受到線程池大小的限制(如果有的話)。
一旦同一線程再次分配給了解 的代碼ThreadLocal
,如果您沒有刪除它,您將看到上一個(gè)請(qǐng)求的舊值。依賴于此是不好的。它可能會(huì)導(dǎo)致難以追蹤的錯(cuò)誤、安全漏洞等。
添加回答
舉報(bào)