ThreadLocal被称作为线程本地变量,或者线程的本地存储。

ThreadLocal可以让每个线程绑定自己的值。

ThreadLocal将变量在每个线程中都创建了一个副本,这样每个线程就可以访问自己内部的副本变量,它们可以通过get()和set()方法来获取默认值,或者将变量设置为当前线程所要保存的副本的值,这样就能避免了线程安全的问题。


ThreadLocal原理

ThreadLocal内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,它的键值为当前ThreadLocal的变量,value为变量副本。ThreadLocalMapThreadLocal的一个内部类。

初始化时,在Thread里,threadLocals为空,通过ThreadLocal变量调用get或set方法就会对threadLocals进行初始化,并且以当前ThreadLocal变量为键值,value为当前ThreadLocal所要保存的值。

然后在当前线程里,如果要使用哪个ThreadLocal变量的副本值,就通过这个ThreadLocal的变量调用get()方法来获取副本值。

ThreadLocal结构图.png


ThreadLocal内存泄漏问题

ThreadLocalMap中使用的key为弱引用,而value为强引用,所以如果ThreadLocal没有被外部引用的情况下,在垃圾回收时,Key会被清理掉。这样,ThreadLocalMap中就会出现key为null的Entry。

如果我们不采取任何措施的话,value永远也无法被GC回收,这样就会产生内存泄露。

ThreadLocalMap实现中已经考虑了这种情况,所以在调用get(),set(),remove()方法时会自动清理掉key为null的记录。