ThreadLocal
ThreadLocal 类主要是解决在多线程情况下让每个线程都拥有属于自己的本地变量,线程之间互不影响,各自拥有各自的 ThreadLocal,从而避免了线程安全的问题。
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class.
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
在 Thread 源代码中有 threadLocals、inheritableThreadLocals 两个变量,这两个变量都为 ThreadLocalMap 类型。ThreadLocalMap 相当于 ThreadLocal 类的专属 HashMap,默认情况下,这两个对象都是 null。只有线程调用 ThreadLocal 类的 get、set 方法时才会创建。
最终的变量是放在了当前线程的 ThreadLocalMap 中,并不是存在 ThreadLocal 上,ThreadLocal 可以理解为只是ThreadLocalMap 的封装,传递了变量值。每个Thread中都具备一个 ThreadLocalMap,而 ThreadLocalMap 可以存储以ThreadLocal 为 key ,Object 对象为 value 的键值对。
ThreadLocal 内存泄露问题
ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用,而 value 是强引用。所以,如果 ThreadLocal 没有被外部强引用的情况下,在垃圾回收的时候,key 会被清理掉,而 value 不会被清理掉。这样一来,ThreadLocalMap 中就会出现 key 为 null 的 Entry。假如我们不做任何措施的话,value 永远无法被 GC 回收,这个时候就可能会产生内存泄露。ThreadLocalMap 实现中已经考虑了这种情况,在调用 set()、get()、remove() 方法的时候,会清理掉 key 为 null 的记录。使用完 ThreadLocal方法后 最好手动调用remove()方法