ThreadLocal一般用来保存多个线程对共享变量的修改使得每个线程都能访问自己修改后的变量值。以前我对ThreadLocal的粗略印象就是它是一个map<线程,该线程对共享变量值>,具体是不是这样,怎样实现的并不清楚。遇到概念比较模糊的知识点,只有去搞懂,才能有所进步,所以下面分析一下;
一 应用:
//用ThreadLocal声明一个共享的变量
//普通类中的实例变量
1.1 测试带ThreadLocal的共享变量
结果:
1.2测试普通的共享变量
结果:
分析:
在1.1和1.2,分别把一个拥有ThreadLocal变量的对象和一个普通变量的对象传个多个线程,然后修改对象中的值。1.1中每个线程所做的修改都能被记录下来,而1.2中每个线程由于共享一个对象中的变量,由于并发的原因只会记录其中的一个值。ThreadLocal的确会记录每个线程对共享变量的修改。
二 源码
ThreadLocal的类图:
类中各实例变量:
final int threadLocalHashCode:用来唯一标识ThreadLocal对象的hashcode,通过该变量与对象数组中的length-1进行与操作,获取保存的对象的位置。
static AtomicInteger nextHashCode: 用来生成唯一hashcode
static final int HASH_INCREMENT: 每次新生成一个hashcode的增量
类中方法:set和get
getMap(Thread t):根据线程t获取线程的ThreadLocal.ThreadLocalMap threadLocals,ThreadLocalMap有点类似hash table,用来存储不同ThreadLocal对象所对应的值,一个线程可以存储通过多个不同的ThreadLocal操作所存储的值。
createMap(Thread t, T firstValue):创建线程t的ThreadLocalMap,并保存该ThreadLocal对象所对应的值为firstValue。
setInitialValue(): 创建该线程的ThreadLocal.ThreadLocalMap,取initialValue()初始化的值,如果map 为空则创建ThreadLocalMap并保存初始值,如果map不为空则直接替换ThreadLocalMap中该ThreadLocal对象所对应的值为初始值,最后返回初始值。
三流程
ThreadLocal存储多个线程操作值的过程如下:每个线程下都会有创建一个ThreadLocalMap,该map中保存了不同ThreadLocal所保存的值,通过操作ThreadLocalMap获取该线程下ThreadLocal对象所对应的值。ThreadLocalMap中保存对象用的是Entry,它继承了虚引用WeakReference,接下来了解一下虚引用。