Android之ThreadLocal笔记
ThreadLocal线程本地变量(副本)——不能用Map代替,因为这样所有线程又会去争夺Map资源,未解决根本问题
多个线程执行时,为了互不干扰资源,因此用到了ThreadLocal。
原理:Thread类里面有一个成员变量ThreadLocalMap,而ThreadLocalMap类里有成员变量entry数组,当我们用ThreadLocal.set值得时候,实际上就是往entry数组添加内容,而entry数组又只属于该线程(Thread)独有的成员变量,因此就可以做到数据在线程之间的相互隔离。存入entry的值是键值对的形式存在,key为ThreadLocal,value是存入的值,因此当线程需要让多个数据隔离的时候,需要new出多个ThreadLocal对象,并存入entry数组。
ThreadLocal如何引起内存泄漏?如何避免?
我们知道,当我们往entry数组里面set ThreadLocal的时候是以键值对的形式存放的,threadlocal为key,存放的需要进行线程隔离的值为value,而源码里面ThreadLocal是弱引用
这就表明在gc执行垃圾回收的时候ThreadLocal会被回收,也就是Map中的某个key会为null,此时该map已经无法通过key取到被回收的threadlocal所对应的value,然而map又指向了该value
因此该value不会被回收,该内存区域依然被占据,因此造成内存泄漏。
当然,ThreadLocal会在get和set的时候进行查询,如果发现key被回收了,那么会清理value,因此value也不是无限增长的情况。
所以,当我们线程执行完毕之后,如果用到了ThreadLocal,那么要在最后添加ThreadLocal.remove();这样就能保证当value被回收。
- 强引用:普通的引用,强引用指向的对象不会被回收;
- 软引用:仅有软引用指向的对象,只有发生gc且gc之后内存还是不足,才会被回收;
- 弱引用:仅有弱引用指向的对象,只要发生gc就会被回收。