ThreadLocal是Java并發(fā)編程中的常用類,可以解決多個線程共享變量問題曙旭,這是不同于“synchronized”的解決方法。
ThreadLocal介紹
ThreadLocal在每個線程中維護(hù)一個映射MAP,每個線程都單獨有一個變量的副本喂走,實現(xiàn)線程間變量隔離捺弦。
在并發(fā)編程中饮寞,我們可能會遇到多個線程使用同一變量的情境孝扛。比如T1,T2幽崩,兩個線程疗琉,T1在操作某對象時T2也同時操作該對象,造成數(shù)據(jù)混亂歉铝,結(jié)果與預(yù)期不符盈简。對于這種情況常用做法是對操作對象進(jìn)行同步處理(synchronized),但是同步操作會降低執(zhí)行效率太示。ThreadLocal提供了另一種方式來解決并發(fā)問題柠贤,每個線程都操作同一個變量的副本,不影響其他線程中該變量的值类缤。
ThreadLocal常用方法
ThreadLocal類主要有get()臼勉,set(T value),remove()餐弱,initialValue()幾個方法宴霸,結(jié)構(gòu)簡單清晰。
- get()方法可以獲得該線程所維護(hù)的Map表膏蚓,如果在之前沒有使用set(T value)方法設(shè)值瓢谢,則會獲得null值,所以建議重寫initialValue()方法驮瞧,自定義默認(rèn)返回值氓扛。
- set(T value)用來設(shè)置當(dāng)前線程中該ThreadLocal對應(yīng)的值,Key是該ThreadLocal的引用论笔。
- remove()方法用來擦除線程中當(dāng)前Threadlocal所映射的值采郎。
- initialValue()是定義默認(rèn)返回值的方法,推薦在使用ThreadLocal時重寫該方法狂魔,自定義默認(rèn)返回值蒜埋。
//創(chuàng)建ThreadLocal時重寫initialValue()方法
public class TestThreadLocal {
private static final ThreadLocal<String> value = new ThreadLocal<String>() {
@Override
protected String initialValue() {
return "Djz";
}
};
}
ThreadLocal總結(jié)
- 使用ThreadLocal可以在每個線程中保存同一個變量的副本,值相同最楷,但是各線程操作的是自己線程中所保存的副本整份,不會互相影響,不同于同步操作思路解決了多線程并發(fā)問題管嬉。
- ThreadLocal類將自己的引用作為Key值皂林,存儲對象作為Value,存儲在每個線程所維護(hù)的Map映射表中蚯撩,這樣設(shè)計可以使Map與線程綁定础倍,當(dāng)線程被銷毀后,所維護(hù)的Map映射表也會被銷毀胎挎。
- 在創(chuàng)建ThreadLocal建議重寫initialValue()方法沟启,因為該方法默認(rèn)返回null值忆家,存在NPE隱患。
- 由于ThreadLocal提供了線程內(nèi)部的局部變量德迹,因此該變量生命周期與線程相同芽卿,當(dāng)線程銷毀時該局部變量也會銷毀。
- 因為ThreadLocal是在每個線程中都存儲一個對象的副本胳搞,因此對內(nèi)存的消耗相比不使用ThreadLocal更大卸例。
- ThreadLocal也解決了變量傳遞問題,在整個線程內(nèi)ThreadLocal所映射的對象全局共享肌毅,降低了編碼時的復(fù)雜度筷转。