ThreadLocal

102 阅读2分钟

1、概述

ThreadLocal不是为了线程间共享数据的问题, 不存在线程安全问题。是线程间资源隔离的一种方式。

2、使用方式

ThreadLocal threadId = new ThreadLocal<>();

3、理解 Thread、ThreadLocal、ThreadLocalMap之间的关系

-Thread 持有 ThreadLocalMap实例

-ThreadLocal通过 Thread.currentThread()获取当前线程的 ThreadLocalMap

-ThreadLocal实例被线程的ThreadLocalMap实例持有,也可以看成被线程持有

4、ThreadLocalMap结构特点

-ThreadLocalMap实现了Map结构, 单独实现了 HashTable的 Entry结构(没有依赖HashMap的Entry结构), 哈希冲突采用线性探测的方式来解决.

-ThreadLocalMap Entry结构 key存放ThreadLocal, value存放设置的值。 key为一个弱引用(当没有强引用存在, 不管内存是否够, 都会在下一次垃圾回收将该对象清除)。

5、ThreadLocalMap 内存泄漏问题

ThreadLocalMap Entry结构 key存放的ThreadLocald为弱引用好处, 当ThreadLocal的强引用被回收, 在下一次GC key就会被回收, 加快了key内存的释放, 但是value没有被释放

-当ThreadLocal对象的强引用被回收, 在下一次GC的时候弱引用key也会被回收,由于value被Entry强引用, 没有用处内存还没有释放

-在线程执行结束前会出现内存泄漏问题,当线程不复用&线程执行很快结束,影响不大,如果线程还在一直复用&执行时间较长会加大内存泄漏的影响

-使用结束使用ThreadLocal的remove()方法, 释放掉value,避免内存泄漏的影响

6、使用场景

-实现单个线程单例以及单个线程上下文信息存储,比如交易id等

-实现线程安全:非线程安全的对象使用ThreadLocal之后就会变得线程安全,因为每个线程都会有一个对应的实例

-承载一些线程相关的数据,避免在方法中来回传递参数