ThreadLocal源码解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: ThreadLocal源码解析

@[toc]

前言

  • ThreadLocal 想必大家都非常熟悉了,这个不再多做ThreadLocal 的使用案例,,如果有不熟悉的小伙伴 可以阅读

ThreadLocal的源码

本节 我们详细了解ThreadLocal的源码,让大家更为了解ThreadLocal

ThreadLocalMap

在这里插入图片描述
ThreadLocal中的嵌套内部类ThreadLocalMap,这个类本质上是一个map,和HashMap之类的实现相似,依然是key-value的形式,其中有一个内部类Entry,其中key可以看做是ThreadLocal实例,但是其本质是持有ThreadLocal实例的弱引用

在这里插入图片描述
ThreadlocalMap 会发现他是ThreadLocal 的一个内部类,

会发现他有一个Entry

**Entry继承WeakReference,使用弱引用,可以将ThreadLocal对象的生命周期和线程生命周期解绑,持有对ThreadLocal的弱引用,可以使得ThreadLocal在没有其他强引用的时候被回收掉,这样可以避免因为线程得不到销毁导致ThreadLocal对象无法被回收。并且
他是 以key value 形式的Entry **

有兴趣的同学可以打开 底层源码看下具体实现

initialValue

在这里插入图片描述

initialValue ThreadLocal初始化的方法,默认为 null ,可以重写

在这里插入图片描述

get 方法

会发现他把 Thread.currentThread(); 传到 getMap() 方法中,
在这里插入图片描述
调用Thread 类 中定义的 Threadlocal.ThreadlocalMap() 返回一个map
判断当前线程的map是否存在,不为空, 获取当前Entry 实例,
判断这个键值对是否为空
如果不是空,就返回对应的value值
此处是当前线程的map不存在,返回setInitialValue,为空返回初始化值

这里有个非常重要的知识,initialValue 是使用懒加载 ,只有调用 get 的时候才会 使用initialValue 方法,在 new ThreadLocal 中是不会初始化的


private T setInitialValue() {
    //获取初始化值,默认为null(如果没有子类进行覆盖)
    T value = initialValue();
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    //不为空不用再初始化,直接调用set操作设值
    if (map != null)
        map.set(this, value);
    else
        //第一次初始化,createMap在上面介绍set()的时候有介绍过。
        createMap(t, value);
    return value;
}

接下来我们看下 set的方法

set方法

在这里插入图片描述
调用Thread 类 中定义的 Threadlocal.ThreadlocalMap() 返回一个map
判断当前线程的map是否存在,如果ThreadLocal中有这个map,就把当前类和对应的值传进去

如果没有这个map,就新建一个t线程的ThreadLocalMap,并将value值传进去

remove方法

在这里插入图片描述
remove方法就比较简单了

相关文章
|
19天前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
39 0
|
19天前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
29 0
|
19天前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
33 0
|
17天前
|
存储
让星星⭐月亮告诉你,HashMap的put方法源码解析及其中两种会触发扩容的场景(足够详尽,有问题欢迎指正~)
`HashMap`的`put`方法通过调用`putVal`实现,主要涉及两个场景下的扩容操作:1. 初始化时,链表数组的初始容量设为16,阈值设为12;2. 当存储的元素个数超过阈值时,链表数组的容量和阈值均翻倍。`putVal`方法处理键值对的插入,包括链表和红黑树的转换,确保高效的数据存取。
39 5
|
18天前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
|
18天前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
19天前
|
算法 Java 程序员
Map - TreeSet & TreeMap 源码解析
Map - TreeSet & TreeMap 源码解析
29 0
|
19天前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
44 0
|
2月前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
115 29
什么是线程池?从底层源码入手,深度解析线程池的工作原理
|
2月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
335 37

推荐镜像

更多