JDK-ThreadLocal

ThreadLocal

ThreadLocal意为线程本地变量, 使用了Thread类的域-ThreadLocalMap来实现数据的线程范围访问. 不同的线程操作的是各自的ThreadLocalMap.

ThreadLocalMap本质是一个使用线性探测法实现的一个HashMap. 这个map的key是ThreadLocal对象, value是存储元素.

ThreadLocalMap继承了WeakReference, 它的key是弱引用. 这么做的方式是防止内存泄露:

  • 强引用key:ThreadLocal被设置为null,由于ThreadLocalMap持有ThreadLocal的强引用,如果不手动删除,那么ThreadLocal将不会回收,产生内存泄漏。

  • 弱引用key:ThreadLocal被设置为null,由于ThreadLocalMap持有ThreadLocal的弱引用,即便不手动删除,ThreadLocal仍会被回收ThreadLocalMap在之后调用set()、getEntry()和remove()函数时会清除所有key为null的Entry。

需要注意的问题:

  • ThreadLocalMap仅仅含有这些被动措施来补救内存泄漏问题。如果你在之后没有调用ThreadLocalMap的set()、getEntry()和remove()函数的话,那么仍然会存在内存泄漏问题。
    在使用线程池的情况下,如果不及时进行清理,内存泄漏问题事小,甚至还会产生程序逻辑上的问题。所以,为了安全地使用ThreadLocal,必须要像每次使用完锁就解锁一样,在每次使用完ThreadLocal后都要调用remove()来清理无用的Entry。

  • 子线程可继承父线程的ThreadLocal -> InheritableThreadLocal