ThreadLocal--实现原理、内部结构
ThreadLocal的实现原理
Thread类中有threadLocals和inheritableThreadLocals两个变量,它们都是ThreadLocalMap类型的变量. 其实每个线程的本地变量不是存放在ThreadLocal实例(对象)里面,而是存放在调用线程的threadLocals变量里面。ThreadLocal就是一个工具壳,它通过set方法把value值放入调用线程的threadLocals变量里面并存放起来,当调用线程调用它的get方法时,再从当前线程的threadLocals变量里面将其拿出来使用。
如果调用线程一直不终止,那么这个本地变量会一直存放在调用线程的threadLocals变量里面,所以当不需要使用本地变量时可以通过调用ThreadLocal变量的remove方法,从当前线程的threadLocals里面删除该本地变量,否则可能会造成内存溢出。另外,Thread里面的threadLocals为何被设计为map结构?很明显是因为每个线程可以关联多个ThreadLocal变量。
具体的过程是这样的:
(1) 每个Thread线程内部都有一个Map (ThreadLocalMap)
(2) Map里面存储ThreadLocal对象(key)和线程的变量副本(value)
(3)Thread内部的Map是由ThreadLocal维护的,由ThreadLocal负责向map获取和设置线程的变量值。
(4)对于不同的线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,互不干扰。
这个设计与我们一开始说的设计刚好相反,这样设计有如下两个优势:
(1) 这样设计之后每个Map
存储的Entry
数量就会变少。因为之前的存储数量由Thread
的数量决定,现在是由ThreadLocal
的数量决定。在实际运用当中,往往ThreadLocal的数量要少于Thread的数量。
(2) 当Thread
销毁之后,对应的ThreadLocalMap
也会随之销毁,能减少内存的使用。