ThreadLocal
ThreadLocal線程局部變量,每個線程都維護一個ThreadLocal相關的地址空間,相當於每個線程都有一個自己的數據保存地,不會互相影響;以空間換時間的策略。
原理分析
分析ThreadLocal源碼可知:使用ThreadLocal後,每個線程都維護着一個Map,而Map裏存着Entry對象;key爲ThreadLocal對象,值爲ThreadLocal 的set方法設置的值(即我們保存在ThreadLocal裏的值),這中結構意味着在一個線程裏同一個ThreadLocal對象只能設置一個值,因爲key不可重複;而Map裏可存入多個Entry,但是通過不同的ThreadLocal來實現;
Map中存的Entry對象的key是個虛引用,因爲虛引用在GC時會回收虛引用所指向的空間。使用虛引用是當我們線程中ThreadLocal對象的引用t1爲null時,可以將ThreadLocal對象所佔據的內存空間回收,避免內存泄漏,但還是有內存泄漏的危險,當ThreadLocal對象被回收後,key將爲null,而原來根據key可找到的value將不能再被訪問到,因此在使用ThreadLocal時千萬千萬要注意當使用完之後一定一定要調用remove() 方法將值移除。
具體的使用如下
import java.util.concurrent.TimeUnit;
public class ThreadLocal {
//volatile static Person p = new Person();
static ThreadLocal<Person> tl = new ThreadLocal<>();
public static void main(String[] args) {
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(tl.get());
}).start();
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
tl.set(new Person());
}).start();
}
static class Person {
String name = "zhangsan";
}
}