THREADLOCAL

- 理解:每个线程会持有threadlocalMap;
- 可以创建多个threadlocal对象
- threadlocalmap是一个entry的数组


- 根据当前线程找到当前现成的threadlocalma的entry的数组
- entry<THREADLOCAL-WEAK引用, 存的值>

- KEY:threadlocal对象的弱引用
- value:你存的值
Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t);
ThreadLocal内存溢出问题:
- 我们可以发现 get 和set 方法都可能触发清理方法expungeStaleEntry(),所以正常情况下是不会有内存溢出的。
- 是如果我们没有调用get和set的时候就会可能面临着内存溢出。
- 就算我们没有调用get和set和remove方法,线程结束的时候,也就没有强引用再指向ThreadLocal中的ThreadLocalMap了,这样ThreadLocalMap和里面的元素也会被回收掉。
- 但是有一种危险是,如果线程是线程池的,在线程执行完代码的时候并没有结束,只是归还给线程池,这个时候ThreadLocalMap和里面的元素是不会回收掉的。
整理
- 如果对象不持有threadlocal的没有强引用
- 那么threadlocalMap中的key作为threadlocal作为弱引用就会被回收,那么出现entry为 null - value 状态,这种状态在getsetremove状态下会清理
- 在threadlocalmap的get set 会进行判断,当map中key为null的话就会进行删除(expungeStaleEntry())方法
- ThreadLocal内存泄漏的根源是 :由于ThreadLocalMap的生命周期跟Thread一样长,而不是threadlocal,如果没有手动删除对应key就会导致内存泄漏,而不是因为弱引用。
- 如果threadlocal对象的持有已经丢失,在没人调用getsetremove,他的value在threadlocalmap中被引用不会丢失,threadlocalmap与thread存活时间一样长,在线程池的状态下会容易复现
