ThreadLocal源码分析---简单易懂
大家都知道ThreadLocal的用途功能,就是给不同线程创建一个副本,使他们在调用的时候互不形象。那这个线程的源码是如何实现的,接下来我用简单的图片加源码的形式来给大家说明。
如图Thead和Threadlocal类之间的关系
如图我们可以清楚的知道ThreadLocal类里面有个内部静态类ThreadLocalMap,而Threa类里面有个这个内部静态类ThreadLocalMap的实例theadLocals,清楚他们的结构后就可以对他们的源码进行分析了。
首先我们先理解一下ThreadLocalMap这个静态类是什么
ThreaLocalMap里面还有一个内部类Entry,Entry就是一个键值对,key是ThreadLocal<?>,value是Object,细心的读者可以发现其实这个ThreadLocalMap就是一个HashMap< ThreadLocal<?>, Object>,用来记录每个线程中每个ThreadLocal对应的value。
ThreadLocal的set()方法:
/**
* Sets the current thread's copy of this thread-local variable
* to the specified value. Most subclasses will have no need to
* override this method, relying solely on the {@link #initialValue}
* method to set the values of thread-locals.
*
* @param value the value to be stored in the current thread's copy of
* this thread-local.
*/
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t); //得到当前线程的theadLocals
if (map != null)
map.set(this, value); //这个this是指threadLocal的实例,把值设置到当前线程的theadLocals
else
createMap(t, value);
从代码可以看出set(T value)分别调用了getMap(t), 这个方法返回的是当前线程的theadLocals,如果map不为空就把key = ThreadLocal<?>,value = Object的形式设置到map里面,如果为空的话,就要初始化这个theadLocals了(theadLocals就是map)
getMap(t)的源代码,返回的是当前线程的theadLocals如图
map.set(this, value);这个方法的原理其实就是Hashmap里面的put方法,把键值加进去,这里我就不说了
我们来看看createMap(t, value)这个方法,其实这个方法就是初始化当前线程的threadLocals,应为Thread实例化的时候,这个threadLocals实例变量是为null的。!在这里插入图片描述
这里调用了ThreadLocalMap的构造函数,如图
这个ThreadLocalMap的构造函数其实就是初始化容器table,并把第一个key,value放进去。
我们来看看get()方法
先得到当前线程的threadLocals,然后判断这个threadLocals是不是为null,为null的话就调用setInitialValue()进行初始化,不为空的话直接获取,再来看看setInitialValue()这个方法的源代码
在这里,这个方法有尝试获取当前线程的localThreads,并判断是否为null,为null就调用createMap(t, null)来进行初始化,initialValue()返回的是一个固定的null值,localThreads不为null的话就把null座位value设置进去,最后返回value(也就是null值)。
ThreadLocal的主要源代码就是上面了,希望对你有所帮助。