码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 面试分析:你懂不懂threadlocal?


    目录

    ThreadLocal

    应用场景

    get与set方法

    ThreadLocalMap

    ThreadLocalMap.set

     ThreadLocalMap.get

     ThreadLocalMap.remove

    线程隔离

    内存泄漏


    今天看一个面试题,threadlocal的原理

    首先,要知道threadlocal是什么,如果都不知道这个是什么,那就也别看什么原理了.....

    ThreadLocal

    threadlocal 是线程的内部存储类,可以在指定线程内存储数据,且只有指定线程可以拿到数据

    说白了,就是为了数据安全

    不同的线程在使用 threadlocal 的时候,都会有自己的一个 threadlocalmap 对象,并且通过 threadlocal 进行管理

    每个新线程都会被实例化一个 threadlocalmap,并且赋值给 threadLocals,如果已经存在了 threadLocals,那就直接复用

    应用场景

    那种作用域是线程,并且不同的线程还会有不同的副本的时候,就可以考虑用 threadlocal

    当然,如果说业务处理逻辑强依赖与 副本变量,那可能就不大适合这玩意了

    get与set方法

    这一块我们可以直接看源码就行

    1. public void set(T value) {
    2. Thread t = Thread.currentThread();
    3. ThreadLocalMap map = getMap(t);
    4. if (map != null)
    5. map.set(this, value);
    6. else
    7. createMap(t, value);
    8. }
    1. public T get() {
    2. Thread t = Thread.currentThread();
    3. ThreadLocalMap map = getMap(t);
    4. if (map != null) {
    5. ThreadLocalMap.Entry e = map.getEntry(this);
    6. if (e != null) {
    7. @SuppressWarnings("unchecked")
    8. T result = (T)e.value;
    9. return result;
    10. }
    11. }
    12. return setInitialValue();
    13. }

    可以看到,无论是 get 还是 set,都是用的 ThreadLocalMap 的方法

    ThreadLocalMap

    ThreadLocalMap 为每个 thread 都维护了一个数组 table,threadllcal 确定了一个数组下标,而这个下标是value存储的对应位置

    从之前的 set 源码,我们可以得到,ThreadLocalMap 是一个延迟创建的结构,也就是说,至少要放置一个内容时才会创建

    而通过创建 ThreadLocalMap 的源码,我们可以得到,ThreadLocalMap 初始化时创建了默认长度是16的 Entry 数组。通过 hashCode 与 length 位运算确定索引值 i

    ThreadLocalMap.set

    我们来看看 threadLocalMap 的 set 方法

     ThreadLocalMap.get

    get 方法没有什么可看的,就直接取就完事了

     ThreadLocalMap.remove

    我们再看看 remove 方法

    1. private void remove(ThreadLocal key) {
    2. Entry[] tab = table;
    3. int len = tab.length;
    4. int i = key.threadLocalHashCode & (len-1);
    5. for (Entry e = tab[i];
    6. e != null;
    7. e = tab[i = nextIndex(i, len)]) {
    8. if (e.get() == key) {
    9. e.clear();
    10. expungeStaleEntry(i);
    11. return;
    12. }
    13. }
    14. }

    可以看到,也没什么东西

    线程隔离

    threadlocal 拥有线程隔离特性,只有线程内可以访问

    类比 synchronized,它是通过线程等待来解决访问冲突问题

    而 threadlocal 是通过空间存储来解决访问冲突问题

    内存泄漏

    注意,threadlocal 有一个地方需要注意,那就是内存泄漏的问题,使用完,一定要 remove,否则永远清除不掉,时间长了就会出问题了

  • 相关阅读:
    Python多线程方案
    真题磨练-20220903美团笔试算法反思学习(持续更新中)
    c语言小课设--通讯录(动态内存管理)
    STM32——端口复用与重映射概述与配置(HAL库)
    基于HTML美食文化网页设计与实现——html+css+javascript+jquery+bootstarp响应式西餐厅美食网站
    在线等!!!新版考纲在国内通过率有多少?
    拒绝“爆雷”!GaussDB(for MySQL)新上线了这个功能
    算法题中常用的工具类的方法(Java)
    8月3日第壹简报,星期三,农历七月初六
    C++ STL学习 —— 模板、泛型算法、函数对象、lambda 表达式(参数捕获)、函数适配器
  • 原文地址:https://blog.csdn.net/weixin_46097842/article/details/126675253
  • 最新文章
  • 龙芯2k0300 - 智能车走马观碑组目标分类算法
    Windows 应用自动上架 Microsoft Store 的自动化实践
    很多企业做了 SBOM,为什么依然管不住依赖?
    别让AI再从零写一堆优美的屎山了
    A 股回测中的复权与 Point-in-Time 偏差:一次数据泄露的工程复盘
    一文理清 HarmonyOS 6.0.2 涵盖的十个升级点
    深度学习进阶(二十四)Swin 的二维 RPE
    Codex CLI 完全使用手册:从入门到精通
    一次线上故障带你看懂 MySQL InnoDB 缓冲池
    Rocky9.3 UEFI 引导崩溃解决办法
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号