ThreadLocal
Posted gqymy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThreadLocal相关的知识,希望对你有一定的参考价值。
ThreadLocal,线程变量,是一个以ThreadLocal对象为键、任意对象为值的存储结构。这 个结构被附带在线程上,可以通过set(T)方法来设置一个值,在当前线程下再通过get()方法获取到原先设置的值
ThreadLocal是保存线程本地化对象的容器。当运行于多线程环境的某个对象使用ThreadLocal维护变量时,ThredLocal为每个使用该变量的线程分配一个独立的变量副本。所以每个线程都可以独立地改变自己的副本,而不会影响到其他线程所对应的副本
InheritableThreadLocal继承于ThreadLocal,它自动为子线程复制一份从父线程那里继承而来的本地变量:在创建子线程时,子线程会接收所有可继承的线程本地变量的初始值。当必须将本地线程变量自动传给所有创建的子线程时,应尽可能使用InheritableThreadLocal
在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序缜密地分析什么时候对变量进行读写、什么时候需要锁定某个对象、什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大;
而ThreadLocal从另一个角度来解决多线程的并发访问。ThreadLocal为每个线程提供了一个独立的变量副本,从而隔离了多个线程对数据访问的冲突。因为每个线程都拥有自己的变量副本,因而也就没有必要对该变量进行同步。ThreadLocal提供了线程安全的对象封装,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
ThreadLocal内存泄漏问题,如何防止
ThreadLocal的实现是这样的:每个Thread 维护一个 ThreadLocalMap 映射表,这个映射表的 key 是 ThreadLocal 实例本身,value 是真正需要存储的 Object。
也就是说 ThreadLocal 本身并不存储值,它只是作为一个 key 来让线程从 ThreadLocalMap 获取 value。值得注意的是图中的虚线,表示 ThreadLocalMap 是使用 ThreadLocal 的弱引用作为 Key 的,弱引用的对象在 GC 时会被回收。
ThreadLocal内存泄漏的根源是:由于ThreadLocalMap的生命周期跟Thread一样长,如果没有手动删除对应key就会导致内存泄漏,而不是因为弱引用。
综合上面的分析,我们可以理解ThreadLocal内存泄漏的前因后果,那么怎么避免内存泄漏呢?
每次使用完ThreadLocal,都调用它的remove()方法,清除数据。
在使用线程池的情况下,没有及时清理ThreadLocal,不仅是内存泄漏的问题,更严重的是可能导致业务逻辑出现问题。所以,使用ThreadLocal就跟加锁完要解锁一样,用完就清理。
以上是关于ThreadLocal的主要内容,如果未能解决你的问题,请参考以下文章