5.ThreadLocal

内容提要
• ThreadLocal能定义线程本地变量;

• 从ThreadLocalMap进一步了解ThreadLocal特性;

• 结合底层代码,深入了解ThreadLocal;

• ThreadLocal可能会导致内存泄漏,如何避免?

• 总结:面试时通过底层代码,全面展示ThreadLocal的方式;

通过ThreadLocal,定义线程本地变量

• 也能通过ThreadLocal存储线程本地变量 ;

• 线程里可以使用定义在主内存里的变量 ;

• 用多个线程去爬取不同的网站,每个线程用自身的 ThreadLocal来维护爬取不成功的列表;

内部数据结构:ThreadLocalMap

• ThreadLocalMap里每个元素是Entry

• 是通过内部的ThreadLocalMap对象来存储本地变量

• 每个Entry是键值对,键是当前ThreadLocal对象,值是本地变量

• Entry是继承WeakReference,是弱引用,之上没强引用时会回收

5.ThreadLocal_第1张图片

内部数据结构:ThreadLocalMap
• 一个线程类里有一个ThreadLocalMap

• 一个线程类里可以有多个ThreadLocal类变量

• 一个ThreadLocalMap里有多个Entry

• 每个Entry存储了一个ThreadLocal本地变量

5.ThreadLocal_第2张图片

 

set方法的源码 

• localVal.set(localVal.get() + 1);,调用时,传入一个参数

• 放入ThreadLocalMap对象,并用当前ThreadLocal对象作为Key

• 如没有ThreadLocalMap对象,则用当前线程t来创建

5.ThreadLocal_第3张图片

创建ThreadLocalMap

• 初始化时,用当前线程作为键


• 通过源代码,能发现ThreadLocalMap里的每个元素是Entry,初始 长度是16,Entry extends WeakReference>
get方法的源码 

• 通过当前线程,得到所属的ThreadLocaMap,以及Entry

• 从Entry里,获得value部分,这就是本线程的本地变量

5.ThreadLocal_第4张图片

 

可能会导致的内存泄漏

• 在ThreadLocal里保存值时,会放入Entry对象
• 但如创建ThreadLocal的线程一直持续运行,那么其中的value就 可能无法回收,

• Entry是基于弱引用,如创建ThreadLocal的线程终止,会回收

• 避免方式,用好ThreadLocal对象,需要及时remove

5.ThreadLocal_第5张图片

总结:如何全面展示ThreadLocal
1. 除了被问到,还可以主动引出:在xx业务里,我们需要用到 ThreadLocal来保存本地变量

2. 讲完业务后同时指出,ThreadLocal的内部实现是ThreadLocalMap

3. 结合ThreadLocal和ThreadLocalMap的源代码,讲述赋值和取值的 细节

4. 结合Entry和弱引用,讲述可能引发内存泄漏,同时说下如何避免

5. 通过本小节给出说辞,大家不仅能展示“存储线程本地变量”的技能, 还能让面试官感觉你熟悉底层代码,更进一步,还能通过弱引用,引导到垃圾回收话题 

你可能感兴趣的:(多线程)