ThreadLocal 超强图解,这次终于懂了~

手机软件开发 2024-9-8 17:35:58 62 0 来自 中国
媒介

各人好,我是小彭。
在前面的文章里,我们聊到了散列表的开放寻址法和分离链表法,也聊到了 HashMap、LinkedHashMap 和 WeakHashMap 等基于分离链表法实现的散列表。
本日,我们来讨论 Java 标准库中一个利用开放寻址法的散列表结构,也是 Java & Android “口试八股文” 的标准题库之一 —— ThreadLocal。
本文源码基于 Java 8 ThreadLocal。
头脑导图:
2.jpeg 1. 回首散列表的工作原理

在开始分析 ThreadLocal 的实现原理之前,我们先回首散列表的工作原理。
散列表是基于散列头脑实现的 Map 数据结构,将散列头脑应用到散列表数据结构时,就是通过 hash 函数提取键(Key)的特性值(散列值),再将键值对映射到固定的数组下标中,利用数组支持随机访问的特性,实现 O(1) 时间的存储和查询利用。
散列体现意图
在从键值对映射到数组下标的过程中,散列表会存在 2 次散列辩说:

  • 第 1 次 - hash 函数的散列辩说: 这是一样平常意义上的散列辩说;
  • 第 2 次 - 散列值取余转数组下标: 本质上,将散列值转数组下标也是一次 Hash 算法,也会存在散列辩说。
事实上,由于散列表是压缩映射,以是我们无法制止散列辩说,只能包管散列表不会由于散列辩说而失去精确性。常用的散列辩说办理方法有 2 类:

  • 开放寻址法: 比方 ThreadLocalMap;
  • 分离链表法: 比方 HashMap。
开放寻址(Open Addressing)的焦点头脑是: 在出现散列辩说时,在数组上重新探测出一个空闲位置。 经典的探测方法有线性探测、平方探测和双散列探测。线性探测是最根本的探测方法,我们本日要分析的 ThreadLocal 中的 ThreadLocalMap 散列表就是接纳线性探测的开放寻址法。
2. 熟悉 ThreadLocal 线程局部存储

2.1 说一下 ThreadLocal 的特点?

ThreadLocal 提供了一种特别的线程安全方式。
利用 ThreadLocal 时,每个线程可以通过 ThreadLocal#get 或 ThreadLocal#set 方法访问资源在当火线程的副本,而不会与其他线程产生资源竞争。这意味着 ThreadLocal 并不思量怎样办理资源竞争,而是为每个线程分配独立的资源副本,从根本上制止发生资源辩说,是一种无锁的线程安全方法。
用一个表格总结 ThreadLocal 的 API:
public API描述set(T)设置当火线程的副本T get()获取当火线程的副本void remove()移除当火线程的副本ThreadLocal<S> withInitial(Supplier<S>)创建 ThreadLocal 并指定缺省值创建工厂protected API描述T initialValue()设置缺省值2.2 ThreadLocal 怎样实现线程隔离?(重点明确)

ThreadLocal 在每个线程的 Thread 对象实例数据中分配独立的内存地区,当我们访问 ThreadLocal 时,本质上是在访问当火线程的 Thread 对象上的实例数据,差别线程访问的是差别的实例数据,因此实现线程隔离。
Thread 对象中这块数据就是一个利用线性探测的 ThreadLocalMap 散列表,ThreadLocal 对象自己就作为散列表的 Key  ,而 Value 是资源的副本。当我们访问 ThreadLocal 时,就是先获取当火线程实例数据中的 ThreadLocalMap 散列表,再通过当前 ThreadLocal 作为 Key 去匹配键值对。
ThreadLocal.java
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-23 20:17, Processed in 0.154901 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表