ThreadLocal原理的秘密

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

目录

1. ThreadLocal描述

2. 认识ThreadLocalMap

3. 神奇的数字

4.注意


1. ThreadLocal描述

ThreadLocal保证了每个线程都有自己独享的变量,不用考虑并发同步的问题。通常情况下,ThreadLocal类型的变量被建议声明为static,即使多个线程调用多次,该变量也只会初始化一次。ThreadLocal使用起来很简单、方便,但非常值得弄清ThreadLocal的实现原理。

2. 认识ThreadLocalMap

在ThreadLocal内部,有一个静态类(ThreadLocalMap)很关键,ThreadLocalMap声明为 package private, 所以我们无法直接使用它,只能通过与ThreadLocalMap在同一个包下的ThreadLocal访问它,比如使用ThreadLocal的set()和get()方法时,底层实际上在操作ThreadLocalMap。对线程来说,ThreadLocalMap天然就是线程安全的,并不是因为ThreadLocalMap做了很多额外的线程安全操作,而是在Thread类中声明了一个ThreadLocalMap的成员变量(Thread与ThreadLocalMap在同一个包中),所以每个线程都有自己的ThreadLocalMap对象,多个线程互不干扰。一个线程只能有一个ThreadLocalMap变量,但是可以关联多个ThreadLocal变量,下图是他们之间的关系:

上图只描述了Thread和ThreadLocalMap或者Thread和ThreadLocal之间的关系,没有说明ThreaLocalMap和ThreadLocal之间的关系,为了清楚的描述ThreaLocalMap和ThreadLocal之间关系,最好要清楚ThreadLocalMap的内部结构。ThreadLocalMap主要由一个Entry数组构成,Entry有两个成员变量,一个是<ref>, <ref>是一个ThreadLocal类型的对象,一般把<ref>当成key,另一个成员变量是value,value是自定义的,ThreadLocalMap结构和ThreadLocal的关系如下图:

如上图,一个ThreadLocal变量加上一个自定义的value,映射到ThreadLocalMap的一个Entry对象。当使用ThreadLocal的set()和get()方法,设置和查找值时,底层将ThreadLocal对象作为key,实际操作的是ThreadLocalMap中的Entry数组。

3. 神奇的数字

在ThreadLocalMap源码中,有个非常有趣的东西,为了快速查找和设置值,需要找到ThreadLocal对象到ThreadLocalMap的Entry数组下标进行快速映射,所以jdk源码中使用了一个神奇的数字<0x61c88647>,使用这个数字可以得到最佳分布的乘法哈希码,如下面的例子:

        int HASH_CODE = 0;

        int HASH_INCREMENT = 0x61c88647; // magic number

        // generate numbers in 16
        int i=0;
        while(i < 16){
            HASH_CODE = HASH_CODE + HASH_INCREMENT;
            int index = HASH_CODE & (16 - 1);
            System.out.print(index + " ");
            i++;
        }

运行上面的代码,得到结果:

7 14 5 12 3 10 1 8 15 6 13 4 11 2 9 0

输出的结果中产生16以内的任何两个数字都不相等,所以在ThreadLocal源码中,将这个神奇的数字当成了ThreadLocal对象的hashCode,通过类似运算快速定位到ThreadLocalMap中的Entry数组的下标。

4.注意

如果某个线程在执行结束之后,并没有立即销毁,而是被线程池回收,那么该线程的ThreadLocal对象会一直保持不变。

👉👉👉 自己搭建的租房网站:全网租房助手,m.kuairent.com,每天新增 500+房源

深入理解c++11thread_local 理解c++11 thread_localthread_localthread_local的生命周期全局thread_local局部thread_local类内静态成员thread_local总结 thread_local thread_local 是c++的关键字,可以用来修饰全局变量、类的静态成员变量以及函数的局部变量,表示每一个线程都拥有此变量的一个实例拷贝,相当于每个线程都拥有一个变量。例如: thread_local int global_var; // 全局的thread_local变量 voi 阅读详情

相关推荐

Java-ThreadLocal(看这一篇就够了)

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 1、什么是ThreadLocal ThreadLocal class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set

了解➔熟悉➔掌握➔精通 2万+

C++线程本地数据--thread_local类型数据

通过使用关键字thread_local,可以定义线程本地数据。 thread_local 在必要的情况下,我们可以为每个线程创建线程本地数据。 线程局部数据专属于线程,其行为类似于静态数据。 这意味着,它将在第一次使用时创建,其生命周期将绑定到线程的生命周期。 线程本地数据通常称为线程本地存储。 使用线程本地数据非常简单,下面是个小程序: // threadLocal.c...

未来之歌 8939

【Java并发编程】Java多线程(五):关于线程的几个问题

1.子线程 1 去等待子线程 2 执行完成之后才能执行,如何去实现? 答:这里考察的就是 Thread.join 方法,我们可以这么做: @Test public void testJoin2() throws Exception { // 线程2 Thread thread2 = new Thread(new Runnable() { public void run() {...} }); // 线程1 Thread thread1 = new Thread(new Runna

A minor 2041

精通高并发与多线程,却不会用ThreadLocal

大家好,我是小菜,一个渴望在互联网行业做到蔡不菜的小菜。可柔可刚,点赞则柔,白嫖则刚! 死鬼~看完记得给我来个三连哦! 本文主要介绍 ThreadLocal 的使用 如有需要,可以参考 如有帮助,不忘 点赞 ❥ 微信公众号已开启,小菜良记,没关注的同学们记得关注哦! 之前我们有在并发系列中提到 ThreadLocal 类和基本使用方法,那我们就来看下 ThreadLocal 究竟是如何使用的! ThreadLocal 简介 概念 ThreadLocal 类是用来提供线程内部的局部变量。这种变量在多线程

Cbuc丶的博客 600

volatile的可见性、安全发布的秘密ThreadLocal原理

volatile关键字通过强制线程从主内存读取最新值,确保变量的可见性。它通过插入内存屏障阻止指令重排序,保证写操作立即刷新到主内存,其他线程能立即看到修改。适用于单写多读场景,如状态标志,但无法保证复合操作的原子性。底层通过StoreStore、StoreLoad等内存屏障实现,是轻量级的线程安全解决方案。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 2050

ThreadLocal是怎样炼成的

好久没更新博客了,一直都有学习新知识,但是没时间总结,主要因为顾着去发展模型兴趣去了哈 难得静下来写一篇博客 闲话不多说,直接进入主题缘起两年前因为工作关系,曾经研究过ThreadLocal源码一段时间,不过研究得不够透彻。最近偶然间又接触到ThreadLocal,又有了新的认识,因此写篇博客记录下来,顺便抛砖引玉一下。 网上很多人都会把ThreadLocal类比为Map来实现的,如果你真的这

lzw_2006的专栏 778

ThreadLocal类实现

ThreadLocal是什么? ThreadLocal是java多线程并发中用到的一个类,采用了空间换时间的方法,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 从线程的角度来看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。 ThreadLocal类的接口很简单,只有4个方法:...

c630843901的博客 396

一张图解决ThreadLocal

1

cureking的博客 194

ThreadLocal

ThreadLocal,连接ThreadLocalMapThread。来处理Thread的TheadLocalMap属性,包括init初始化属性赋值、get对应的变量,set设置变量等。通过当前线程,获取线程上的ThreadLocalMap属性,对数据进行get、set等操作。

qq_31849075的博客 170

ThreadLocal 线程本地变量

ThreadLocal 定义 ThreadLocal通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本 在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中...

dingmei1901的博客 183

深入理解ThreadLocal

一、ThreadLocal是什么先看JDK源码中对ThreadLocal的解释: This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set me

积少成多,努力,谦逊,进取。 786

java中的Threadlocal对象

  对于java多线程中的共享对象Threadlocal对象,在不同线程取到的值不同,查看源码实现,其实每个value值并不保存Threadlocal对象中,而是保存在每个线程中的定义的Map型变量Threadlocals中,键值是这个共享变量Threadlocal对象,每个线程有相同的Threadlocal对象作为的键,但value是不一样的。    ...

Ysh-uestc 303

Android消息异步机制(ThreadLocal、MessageQueue、Looper、Handler关系总结)

Android消息异步机制(ThreadLocal、MessageQueue、Looper、Handler关系总结)

weixin_34123613的博客 83

带你了解源码中的 ThreadLocal

这次想来讲讲 ThreadLocal 这个很神奇的东西,最开始接触到这个是看了主席的《开发艺术探索》,后来是在研究 ViewRootImpl 中又碰到一次,而且还发现 Android 中一个小彩蛋,就越发觉得这个东西很有趣,那么便借助主席的这次作业来好好梳理下吧。 提问 开始看源码前,还是照例来思考一些问题,带着疑问过源码比较有条理,效率比较高一点。 大伙都清楚,Android 其实是基于消...

S19870505的专栏 234

《Android开发艺术》读书笔记-消息机制

之前写了一篇文章Android Handler总结 ,介绍了Handler的基本用法和基本原理。本文是读完Android的消息机制的读书笔记, 从源码分析了消息传递的机制, 对于Handler,以及Looper和MessageQueue有了更深刻的理解。 消息机制的概述 主要申明几个概念,也是接上一篇Android Handler总结 中的原理的内容,再阐述几个重要的概念: Handler, 作

very_caiing 255

Netty高性能组件——FastThreadLocal源码解析(细微处见真章)

文章目录1. 前言2. ThreadLocalMap3. FastThreadLocalThread4. FastThreadLocal4.1 InternalThreadLocalMap4.2 FastThreadLocal初始化4.3 FastThreadLocal变量获取及删除总结 原博文,点击这里 1. 前言 netty自行封装了FastThreadLocal以替换jdk提供的ThreadLocal,结合封装的FastThreadLocalThread,在多线程环境下的变量提高了ThreadLoca

weixin_42030357的博客 440

Handler 源码分析面试的疑难杂症

引言 Hanlder 为什么会内存泄漏?为什么Looper死循环不会卡死应用?为什么Handler能用来切换线程?Handler、Looper、MessageQueue、ThreadLocal之间什么关系?接下来看源码学习学习。 Handler 应该是 老生常谈 为什么那么喜欢 Handler 呢? 笔者认为 Handler 是驱动 整个 APP 的关键类 没有它 Activity、Service 等组件都无法正常回调生命周期,但他还不止这些呢。还有一个是Android 只允许主线程去刷新线程 其他非 U

Bee的博客 312

ThreadLocal的那点小秘密

ThreadLocal的内容到这里就结束了,使用方法,实现原理,包括内存泄漏都还是比较简单的。不过有一点比较难搞,因为有太多人去写“ThreadLocal通过拷贝共享变量的方式解决并发安全问题”,导致很多人认为这是ThreadLocal的核心功能,所以无法确认坐在对面的面试官是如何理解ThreadLocal的。

BASK2312的博客 189
上一篇: The secret of ThreadLocal
下一篇: Lock vs Semaphore vs Condition Variable vs Monitor
祥先生
博客等级 码龄14年 48粉丝 25原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值