线程存储类——ThreadLocal

2018-09-02  本文已影响0人  Samuel_Tom

1、什么是ThreadLocal

ThreadLocal是一个线程本地存储类,不同线程访问同一个ThreadLocal时,不管是set()还是get()方法,对ThreadLocal所做的读写操作都仅限于各自线程内部,互不干扰。

2、ThreadLocal的内部原理

ThreadLocal内部的存储数据结构是一个自定义的类似于HashMap的ThreadLocalMap,属于ThreadLocal的内部类;ThreadLocalMap的Entry继承了WeakReference并使用ThreadLocal为Key值,Entry的Value值为泛型,可以指定任意数据类型的副本变量,ThreadLocalMap其余实现于HashMap的实现基本类似。

set()方法:由于每一个Thread都维护了一个ThreadLocalMap,所以调用set方法时先通过Thread.currentThread()获取当前线程,然后根据当前线程通过getMap()获取对应的ThreadLocalMap,如果map为空则进行初始化,否则调用set(this, value)以ThreadLocal为Key值,线程的变量副本为Value值进行存储。

get()方法:同样通过获取当前线程来获取ThreadLocalMap,并以当前ThreadLocal为Key值通过getEntry()方法获取对用的线程变量副本。

总结:

通过源代码可以看到每个线程都可以独立修改属于自己的副本而不会互相影响,从而隔离了线程和线程.避免了线程访问实例变量发生安全问题. 同时我们也能得出下面的结论:
(1)ThreadLocal只是操各自作Thread中的ThreadLocalMap对象的集合;
(2)ThreadLocalMap变量属于线程的内部属性,不同的线程拥有完全不同的ThreadLocalMap变量;
(3)线程中的ThreadLocalMap变量的值是在ThreadLocal对象进行set或者get操作时创建的;
(4)使用当前线程的ThreadLocalMap的关键在于使用当前的ThreadLocal的实例作为key来存储value值;
(5)ThreadLocal模式至少从两个方面完成了数据访问隔离,即纵向隔离(线程与线程之间的ThreadLocalMap不同)和横向隔离(不同的ThreadLocal实例之间的互相隔离);
(6)线程局部变量时通过一个 Entry 保存在map中,该Entry 的key是一个 WeakReference包装的ThreadLocal, value为线程局部变量,key 到 value 的映射是通过:ThreadLocal.threadLocalHashCode & (INITIAL_CAPACITY - 1) 来完成的;

多图深入分析ThreadLocal原理

上一篇 下一篇

猜你喜欢

热点阅读