线程故事:Web应用程序中的ThreadLocal
ThreadLocal是一種經(jīng)典的候選人,可以輕松在Web應(yīng)用程序中創(chuàng)建類加載器泄漏。 服務(wù)器正在管理池中的線程。 這些線程的壽命比您的Web應(yīng)用程序更長(zhǎng)。 實(shí)際上,直到底層JVM死亡,它們才完全消失。 現(xiàn)在,如果將ThreadLocal放入引用類的對(duì)象的池線程中,則必須*小心。 您需要確保使用ThreadLocal.remove()再次刪除此變量。 Web應(yīng)用程序中的問(wèn)題是:安全刪除ThreadLocal變量的正確位置在哪里? 此外,您可能不想每次同事決定將另一個(gè)ThreadLocal添加到托管線程時(shí)都修改該“刪除代碼”。
我們圍繞線程局部開(kāi)發(fā)了一個(gè)包裝器類,該類將所有線程局部變量保留在一個(gè)單獨(dú)的ThreadLocal變量中。 這是代碼。
public class ThreadLocalUtil {private final static ThreadLocal<ThreadVariables> THREAD_VARIABLES = new ThreadLocal<ThreadVariables>() {/*** @see java.lang.ThreadLocal#initialValue()*/@Overrideprotected ThreadVariables initialValue() {return new ThreadVariables();}};public static Object getThreadVariable(String name) {return THREAD_VARIABLES.get().get(name);}public static Object getThreadVariable(String name, InitialValue initialValue) {Object o = THREAD_VARIABLES.get().get(name);if (o == null) { THREAD_VARIABLES.get().put(name, initialValue.create());return getThreadVariable(name);} else {return o;}}public static void setThreadVariable(String name, Object value) {THREAD_VARIABLES.get().put(name, value);}public static void destroy() {THREAD_VARIABLES.remove();} }public class ThreadVariables extends HashMap<String, Object> { }public abstract class InitialValue {public abstract Object create();}實(shí)用程序類的優(yōu)點(diǎn)是無(wú)需開(kāi)發(fā)人員就可以單獨(dú)管理線程局部變量的生命周期。 該類將所有線程局部變量放在一個(gè)變量映射中。 可以調(diào)用destroy()方法,在其中可以安全地刪除Web應(yīng)用程序中的所有線程本機(jī)。 在我們的例子中,這就是ServletRequestListener -> requestDestroyed()方法。 您還需要將finally塊放置在其他位置。 典型的地方是HttpServlet的init() , doPost() , doGet()方法附近。 完成請(qǐng)求或意外引發(fā)異常后,這可能會(huì)刪除池工作線程中的所有線程本地。 有時(shí)會(huì)發(fā)生服務(wù)器的main線程泄漏線程局部變量的情況。 如果是這種情況,則需要找到正確的位置來(lái)調(diào)用ThreadLocalUtil -> destroy()方法。 為此,要弄清楚主線程實(shí)際上在哪里創(chuàng)建線程變量。 您可以使用調(diào)試器來(lái)做到這一點(diǎn)。
許多人建議出于多種原因而在Web應(yīng)用程序中省略ThreadLocal 。 在池化線程環(huán)境中刪除它們可能非常困難,以便您可以安全地取消部署應(yīng)用程序。 ThreadLocal變量可能有用,但是在應(yīng)用它們之前考慮其他技術(shù)是很公平的。 Web應(yīng)用程序可以攜帶請(qǐng)求范圍參數(shù)的替代方法是HttpServletRequest 。 許多Web框架允許通用的請(qǐng)求參數(shù)訪問(wèn)以及請(qǐng)求/會(huì)話屬性訪問(wèn),而無(wú)需與本地Servlet / Portlet API綁定。 同樣,許多框架支持請(qǐng)求使用依賴項(xiàng)注入將作用域Bean注入到對(duì)象樹(shù)中。 所有這些選項(xiàng)都滿足大多數(shù)要求,因此在使用ThreadLocal之前應(yīng)考慮這些選項(xiàng)。
參考:線程故事: JCG合作伙伴 Niklas的Web應(yīng)用程序中的ThreadLocal。
翻譯自: https://www.javacodegeeks.com/2012/05/threading-stories-threadlocal-in-web.html
總結(jié)
以上是生活随笔為你收集整理的线程故事:Web应用程序中的ThreadLocal的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 攀升科技显卡项目立项,解决核心计算组件国
- 下一篇: Apache JMeter:随心所欲进行