面试官:小伙子,听说你看过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?

ThreadLocal中ThreadLocalMap的数据结构?

ThreadLocalMap的Hash算法?

ThreadLocalMap中Hash冲突如何解决?

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