ThreadLocal理解和應用

2021-10-03 08:36:04 字數 2671 閱讀 6443

本篇部落格將為大家介紹一下threadlocal。從用途、使用方法、原理、及常見問題四個方面來介紹。

threadlocal用途可以理解成乙個「儲物間」,這個「儲物間」當中擁有大量的「儲物櫃」,每個「儲物櫃」實際上就是每個執行緒,當中存放的是thread執行緒中引數,針對於threadlocal的set方法其實就是將引數放入到當前執行緒對應的「儲物櫃」當中(根據thread.currentthread()進行區分執行緒),同樣get()和remove()方法也是一樣。

下面我們編寫乙個程式,每個執行緒儲存乙個自己的id資料,然後多次呼叫進行修改id資料並將其列印。

public class threadlocalids ;

}; public static int getintvalue()

public static void remove()

}

public class threadlocaltest 

}).start();

new thread(new runnable()

}).start();

new thread(new runnable()

}).start();

} private static void increment()

} finally

}}

最後**的執行結果如下,可以看到每個執行緒的id都是依次從0開始增加。

當前執行緒名:main ,no.0, intvalue=0

當前執行緒名:main ,no.1, intvalue=1

當前執行緒名:main ,no.2, intvalue=2

當前執行緒名:main ,no.3, intvalue=3

當前執行緒名:main ,no.4, intvalue=4

當前執行緒名:main ,no.5, intvalue=5

當前執行緒名:thread-0 ,no.0, intvalue=0

當前執行緒名:thread-0 ,no.1, intvalue=1

當前執行緒名:thread-0 ,no.2, intvalue=2

當前執行緒名:thread-0 ,no.3, intvalue=3

當前執行緒名:thread-0 ,no.4, intvalue=4

當前執行緒名:thread-0 ,no.5, intvalue=5

當前執行緒名:thread-1 ,no.0, intvalue=0

當前執行緒名:thread-1 ,no.1, intvalue=1

當前執行緒名:thread-1 ,no.2, intvalue=2

當前執行緒名:thread-1 ,no.3, intvalue=3

當前執行緒名:thread-1 ,no.4, intvalue=4

當前執行緒名:thread-1 ,no.5, intvalue=5

當前執行緒名:thread-2 ,no.0, intvalue=0

當前執行緒名:thread-2 ,no.1, intvalue=1

當前執行緒名:thread-2 ,no.2, intvalue=2

當前執行緒名:thread-2 ,no.3, intvalue=3

當前執行緒名:thread-2 ,no.4, intvalue=4

當前執行緒名:thread-2 ,no.5, intvalue=5

1.threadlocal類結構:

threadlocal擁有三個方法,set(),get(),remove()以及內部類threadlocalmap

2.threadlocal及thread之間的關係

從上面這張圖可以看到thread中屬性threadlocal是作為乙個特殊的map,它的key值就是我們threadlocal例項,而value值就是我們設定的值。

然後我們看一下threadlocal類的原始碼:

public t get() 

}return setinitialvalue();

}threadlocalmap getmap(thread t)

第二行**getmap就是當前的執行緒中獲取我們設定的id值。如果是第一次來呼叫get方法,會執行初始值的操作,也就是我們賦值的0.

上面threadlocal的原始碼中有一行是從threadlocalmap.entry進行獲取,entry類這個是弱引用,弱引用的**是在jvm的下一次gc**之前。

那麼我們可以總結一下threadlocal出現記憶體洩漏的條件:

threadlocal的引用設定為null,且後續沒有任何操作。

執行緒池中使用,執行緒一直執行沒有停止。

觸發了minor gc或者是full gc(這一條是根據其他大牛的部落格得來)

平常我們在使用threadlocal時可以盡量申明為private static final或者使用之後進行remove(),這兩種方法都可以避免出現記憶體洩漏的問題。 

JAVA基礎特性 ThreadLocal 應用

threadlocal是什麼呢?其實threadlocal並非是乙個執行緒的本地實現版本,它並不是乙個thread,而是thread local variable 執行緒區域性變數 也許把它命名為threadlocalvar更加合適,他實現了執行緒的變數隔離,不同的執行緒可以維護自己的變數,他在內部...

ThreadLocal個人理解

為了加深理解,將最近對threadlocal的了解和原始碼分析記錄總結一下。threadlocal可以為執行緒提供區域性變數。使用threadlocal的get 方法,可以在當前執行緒能夠訪問的類和方法中,得與當前執行緒相關聯的變數值。不過,執行緒區域性變數並不是由threadlocal物件儲存維護...

ThreadLocal個人理解

每乙個thread物件中有乙個threadlocalmap的map屬性 該map的key是乙個弱引用 key被weakreference物件指向 當gc時就會 該entry就會 map屬性,避免了記憶體洩漏 當使用threadlocal時,當threadlocal屬性作為map的key,將當前執行緒...