java中的ThreadLocal

Posted wagne

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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,它继承了虚引用WeakReference,接下来了解一下虚引用。
技术分享图片


















以上是关于java中的ThreadLocal的主要内容,如果未能解决你的问题,请参考以下文章

mySQL在java中的应用

Java中的ArrayList 重要方法补充

Java中的Math函数

使用java 8中的forEach(..)而不是java 5中的forEach循环的任何优势[重复]

Java中的数据类型

java - 为啥在java中的poll方法之后PriorityQueue中的值会发生变化? [复制]