精通高并发与多线程,却不会用ThreadLocal?( 三 )
执行流程:
- 首先获取当前线程 , 并根据当前线程获取一个 map
- 如果获取的 map 不为空 , 则将参数设置到 map 中(当前 ThreadLocal 的引用作为 key )
- 如果 Map 为空 , 则给该线程创建 map, 并设置初始值
public T get() {// 获取当前线程对象Thread t = Thread.currentThread();// 获取此线程对象中维护的ThreadLocalMap对象ThreadLocalMap map = getMap(t);// 如果此map存在if (map != null) {// 以当前的ThreadLocal 为 key , 调用getEntry获取对应的存储实体eThreadLocalMap.Entry e = map.getEntry(this);// 对e进行判空if (e != null) {@SuppressWarnings("unchecked")// 获取存储实体 e 对应的 value值// 即为我们想要的当前线程对应此ThreadLocal的值T result = (T)e.value;return result;}}return setInitialValue();}private T setInitialValue() {// 调用initialValue获取初始化的值// 此方法可以被子类重写, 如果不重写默认返回nullT value = http://kandian.youth.cn/index/initialValue();// 获取当前线程对象Thread t = Thread.currentThread();// 获取此线程对象中维护的ThreadLocalMap对象ThreadLocalMap map = getMap(t);// 判断map是否存在if (map != null)// 存在则调用map.set设置此实体entrymap.set(this, value);else// 如果当前线程不存在ThreadLocalMap对象则调用createMap进行ThreadLocalMap对象的初始化// 并将 t(当前线程)和value(t对应的值)作为第一个entry存放至ThreadLocalMap中createMap(t, value);// 返回设置的值valuereturn value;}复制代码
执行流程:- 首先获取当前线程 , 根据当前线程获取一个 map
- 如果获取的 map 不为空 , 则在 map 中以 ThreadLocal 的引用作为 key 来在 map 中获取对应的 Entry entry, 否则跳转到第四步
- 如果 Entry entry 不为空, 则返回 entry.value, 否则跳转到第四步
- map 为空或者 entry 为空 , 则通过 initialValue 函数获取初始值 value, 然后用 ThreadLocal 的引用和 value 作为 firstKey 和 firstValue 创建一个新的 map
public void remove() {// 获取当前线程对象中维护的ThreadLocalMap对象ThreadLocalMap m = getMap(Thread.currentThread());// 如果此map存在if (m != null)// 存在则调用map.removem.remove(this);}// 以当前ThreadLocal为key删除对应的实体entryprivate void remove(ThreadLocal> key) {Entry[] tab = table;int len = tab.length;int i = key.threadLocalHashCodefor (Entry e = tab[i];e != null;e = tab[i = nextIndex(i, len)]) {if (e.get() == key) {e.clear();expungeStaleEntry(i);return;}}}复制代码
执行流程:- 首先获取当前线程 , 并根据当前线程获取一个 map
- 如果获得的map 不为空 , 则移除当前 ThreadLocal 对象对应的 entry
protected T initialValue() {return null;}复制代码
在源码中我们可以看到这个方法仅仅简单的返回了 null, 这个方法是在线程第一次通过 get () 方法访问该线程的 ThreadLocal 时调用的 , 只有在线程先调用了 set () 方法才不会调用 initialValue () 方法 , 通常情况下 , 这个方法最多被调用一次 。如果们想要 ThreadLocal 线程局部变量有一个除 null 以外的初始值 , 那么就必须通过子类继承 ThreadLocal 来重写此方法 , 可以通过匿名内部类实现 。
【END】
这篇 ThreadLocal 就介绍到这里啦 , 希望读到这里的小伙伴能够有所收获 。
- 精英|业务流程图怎么绘制?销售精英的经验之谈
- 广东移动OTN精智专网,助力千行百业数字化转型
- 关闭|虾米音乐的关闭,再次应证了互联网下竞争的规则,小而精很难生存
- 巨人|全国专精特新“小巨人”企业出炉!湖北三峰透平江南专汽入选!
- 手机|年底换机?iQOO 5系列配OriginOS系统将会相当精彩
- Store|苹果将在韩国开设第二家Apple Store直营店 并发布纪念壁
- Pro|Redmi Note 9 5G/Pro正式开售!1299元起每款都精彩
- 黔东南州|黔东南州驻长沙招商分队与猪八戒科技服务有限公司精准对接实施项目
- 5G体温精准筛查大数据系统解决方案(ppt)
- Linux(服务器编程):百万并发服务器系统参数调优