java中的ThreadLocal

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包含值对象value和当前ThreadLocal引用,可能存在ThreadLocal不存在而值继续存在的情况。只有当线程结束,value的对象才能回收。所以最好就是当value不用的时候,自己remove将它释放而不是等到set或get操作(这两个操作也不一定能够收回内存)的时候以免造成内存泄漏。Entry继承了虚引用WeakReference,后面会了解一下虚引用。

posted @ 2018-03-03 16:30  隐秀随风  阅读(269)  评论(0编辑  收藏  举报