ThreadLocal源码阅读六:核心方法get源码探究

背景

  1. 推荐阅读ThreadLocal工作过程、魔数的学习和疑问思考、ThreadLocal解决Hash碰撞
  2. 探究ThreadLocal源码中核心方法get的工作过程及其实现细节。

过程

  • get入口函数
    ThreadLocal源码阅读六:核心方法get源码探究_第1张图片

    注释含义:获取到当前线程的本地变量值的拷贝。如果当前线程没有值,就返回初始化的值。

    细节

      	1. 获取到当前线程。
      	2. 获取到当前线程的ThreadLocalMap实例
      	3. 如果不为空,就根据当前对象this,也就是ThreadLocal,获取到entry实例。
      	4. 如果为空,执行setInitialValue()。其实就是set源码。
    

set源码

  • map.getEntry()
    ThreadLocal源码阅读六:核心方法get源码探究_第2张图片
    注释含义:获取跟key关联的entry实例。因为entry(key,value),其中key是ThreadLocal实例。这是快速访问,就是地址访问,数组访问是O(1),因为数组中存储的是地址,而我们可以计算出来的i其实,访问的时候,就是地址访问到具体内存,无需遍历整个数组。如果没有找到,就执行方法getEntryAfterMiss。

    细节

      	1. 求得当前key所对应的数组下标。
      	2. 根据下标获取到enry实例。
      	3. 如果不为null,而且entry实例的key就是当前的key,那么返回entry实例。
      	4. 如果为null。或者不为null,但是entry实例的key不是当前的key,则执行方法getEntryAfterMiss。
    
  • getEntryAfterMiss(key, i, e)
    ThreadLocal源码阅读六:核心方法get源码探究_第3张图片
    细节

      	1. 如果传递过来的entry实例,这里是e,是null的时候,直接返回null即可。
      	2. 如果传递过来的entry实例,这里是e,不是null的时候。如果k == key,则直接返回e;  如果 k == null, 则需要把下标是i的entry给清除掉即可;如果不满足上面两个条件,则向后遍历整个数组,直到找到或者找不到。找到就返回即可,找不就返回null。
    
  • 理解这样探究源码执行流程有什么意义

    没有,因为代码直接告诉了我们它是怎么工作的,完全没有必要这样一步一步写出来。如果,写出来,也仅仅是加深印象和复习。因为,分析为什么作者把ThreadLocal设计成弱引用,分析环形数组带来利和弊,分析散列算法的特性,分析解决hash冲突原理。懂了这些,研读源码,就没有太大的意义了。但是,正是自己最开始研究源码,才懂得作者为什么这样设计的。

小结

  1. 一步一步写源码执行流程,本身没有太大的意义。因为源码已经告诉了我们它是怎样运作的,而我们仅仅是把英文或者语言语法翻译过来而已,这样做绝对是没有多大意义的。

  2. 那究竟怎么做才是意义?

    以为懂了ThreadLocal是怎么工作的,能够把源码实现的每个细节掌握了,也就是阅读源码没有任何障碍了,其实也是中级阶段。这层还是很好的。

  3. 真正有价值和有意义的是什么?

    那就是懂背后设计的意图。什么意图?就是作者为什么设计环形数组?为什么设计ThreadLocal为弱引用?它用了什么原理来解决hash冲突的?这才是价值。这层是高级阶段。

你可能感兴趣的:(并发编程艺术)