面试官:小伙子,听说你看过ThreadLocal源码?(万字图文深度解析ThreadLocal)

Ym8V9H.png

Ym8V9H.png

(高清无损原图.pdf关注公众号后回复 ThreadLocal 获取,文末有公众号链接)

前几天写了一篇AQS相关的文章:我画了35张图就是为了让你深入 AQS,反响不错,还上了博客园首页编辑推荐,有生之年系列呀,哈哈。

image.png

image.png

这次趁热打铁再写一篇ThreadLocal的文章,同样是深入原理,图文并茂。

全文共10000+字,31张图,这篇文章同样耗费了不少的时间和精力才创作完成,原创不易,请大家点点关注+在看,感谢。

对于ThreadLocal,大家的第一反应可能是很简单呀,线程的变量副本,每个线程隔离。那这里有几个问题大家可以思考一下:

ThreadLocal的key是弱引用,那么在 threadLocal.get()的时候,发生GC之后,key是否为null

ThreadLocalThreadLocalMap数据结构

ThreadLocalMapHash算法

ThreadLocalMapHash冲突如何解决?

ThreadLocalMap扩容机制?

ThreadLocalMap中过期key的清理机制?探测式清理启发式清理流程?

ThreadLocalMap.set()方法实现原理?

ThreadLocalMap.get()方法实现原理?

项目中ThreadLocal使用情况?遇到的坑?

……

上述的一些问题你是否都已经掌握的很清楚了呢?本文将围绕这些问题使用图文方式来剖析ThreadLocal的点点滴滴

全文目录

ThreadLocal代码演示

ThreadLocal的数据结构

GC 之后key是否为null

ThreadLocal.set()方法源码详解

ThreadLocalMap Hash算法

ThreadLocalMap Hash冲突

ThreadLocalMap.set()详解
7.1 ThreadLocalMap.set()原理图解
7.2 ThreadLocalMap.set()源码详解

ThreadLocalMap过期key的探测式清理流程

ThreadLocalMap扩容机制

ThreadLocalMap.get()详解
10.1 ThreadLocalMap.get()图解
10.2 ThreadLocalMap.get()源码详解

ThreadLocalMap过期key的启发式清理流程

InheritableThreadLocal

ThreadLocal项目中使用实战
13.1 ThreadLocal使用场景
13.2 分布式TraceId解决方案

注明: 本文源码基于JDK 1.8

ThreadLocal代码演示

我们先看下ThreadLocal使用示例:

public class ThreadLocalTest {
    private List<String> messages = Lists.newArrayList();

    public static final ThreadLocal<ThreadLocalTest> holder = ThreadLocal.withInitial(ThreadLocalTest::new);

    public static void add(String message) {
        holder.get().messages.add(message);
    }

    public static List<String> clear() {
        List<String> messages = holder.get().messages;
        holder.remove();

        System.out.println("size: " + holder.get().messages.size());
        return messages;
    }

    public static void main(String[] args) {
        ThreadLocalTest.add("一枝花算不算浪漫");
        System.out.println(holder.get().messages);
        ThreadLocalTest.clear();
    }
}

打印结果:

[一枝花算不算浪漫]
size: 0

ThreadLocal对象可以提供线程局部变量,每个线程Thread拥有一份自己的副本变量,多个线程互不干扰。

ThreadLocal的数据结构

image.png

image.png

Thread类有一个类型为ThreadLocal.ThreadLocalMap的实例变量threadLocals,也就是说每个线程有一个自己的ThreadLocalMap。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygssz.html