TreadLocal原理及其使用分析

对于TreadLocal,是有听说的,只是一直没有对它进行很全面的了解,最近因为有机会要用到,所以就找了很多文章看了下,也看了TreadLocal类的源码,总的感觉很多博客的文章说的有点模糊(可能是对于自己,理解不了),这里想总结一下,可能会有其他博文的一些内容。

分析:

(1)ThreadLocal 不是用来解决共享对象的多线程访问问题的,这一点很关键!假设一个变量声明了一个变量为ThreadLocal 类型的,那么这个变量是在每个线程中保留一个副本,而这个副本是保留在线程自身的ThreadLocalMap中;

(2)ThreadLocal和Thread密切联系,每个从Tread类继承的类的对象中都有个ThreadLocalMap,而这个ThreadLocalMap对象有一个entry数组,保存属于这个对象的threadlocal变量,也就是说一个thread之类对象可以使用很多treadlocal变量,而treadlocal变量在对象中保存的方式是键值对的方式,也就是通过entry结构保存,在键值对中,key为threadlocal变量的引用、值为threadlocal变量在线程中的取值。下面逐步分析。

在Thread.java源码中有这么一句:

ThreadLocal.ThreadLocalMap threadLocals = null; 说明每个Thread对象都有一个ThreadLocal.ThreadLocalMap成员变量。

而T hreadLocal.ThreadLocalMap是一个ThreadLocal类的静态内部类。如下所示:

ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {table = new Entry[INITIAL_CAPACITY];int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY – 1);table[i] = new Entry(firstKey, firstValue);size = 1;setThreshold(INITIAL_CAPACITY);} 当在ThreadLocal中进行设值的时候:public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);}ThreadLocalMap getMap(Thread t) {return t.threadLocals;} 首先获取当前线程的引用,然后获取当前线程的ThreadLocal.ThreadLocalMap对象(注意:t.threadLocals变量就是ThreadLocal.ThreadLocalMap的变量),如果该对象为空就创建一个,如下所示:void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);}可以看出:

注意上面的这个this变量就是ThreadLocal的引用,这对于每个线程都是相同的,线程之间不同是ThreadLocal变量在线程中的取值。

每个线程各自有一个ThreadLocal.ThreadLocalMap对象,这个对象保存着ThreadLocal引用为key的值,,ThreadLocal变量在线程中的取值为值。

如果执行get()、set()方法,是对前线程中的ThreadLocalMap中对应的ThreadLocal对象的取值就行操作。

如果你新建一个ThreadLocal的对象,这个对象还是保存在每个线程同一个ThreadLocal.ThreadLocalMap对象之中,因为一个线程只有一个ThreadLocal.ThreadLocalMap对象,这个对象是在第一个ThreadLocal第一次设值的时候进行创建,如上所述的createMap方法。

进一步:

ThreadLocalMap是Thread和ThreadLocal之间的桥梁,每个Thread子类对象都有一个ThreadLocalMap,ThreadLocalMap是ThreadLocal的静态内

部类,而我们在真正使用的时候用到了ThreadLocal和Thread,ThreadLocalMap起到了很好的桥梁作用。

如果有兴趣可以进一步参看

使用双手的是劳工,使用双手和头脑的舵手,

TreadLocal原理及其使用分析

相关文章:

你感兴趣的文章:

标签云: