码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • ThreadLocal


    ThreadLocal

    • ThreadLocal
      • 用法
      • 底层结构
        • ThreadLocal的hash
        • 内存泄漏
        • 过期删除处理

    ThreadLocal

    在多线程情况下,在线程类中使用ThreadLocal可以为每个线程配置私有的对象

        ThreadLocal<Object> threadLocal = new ThreadLocal<>();
    
    • 1

    比如可以这样使用,用 ThreadLocal 保存用户信息,里面的值可以存放用户信息,不是公用属性不会存在多线程并发问题:

    private static ThreadLocal<LoginUserInfo> USER_INFO_CACHE = new ThreadLocal();
    
    • 1

    用法

    他们使用 get()和 set() 方法来获取默认值或将其值更改为当前线程所存的副本的值,从而避免了线程安全问题

    底层结构

    这个类中只有一个ThreadLocal对象,但是每一个线程中都有不同的ThreadLocalMap

    最终的变量是放在了当前线程的ThreadLocalMap中,并将ThreadLocal这个对象的弱引用作为键

    	//ThreadLocal的set方法可以说明一切
        public void set(T value) {
        	//这个t代表当前线程
            Thread t = Thread.currentThread();
            //ThreadLocalMap是ThreadLocal的内部类,这让每个线程都有一个map
            ThreadLocalMap map = getMap(t);
            //map没有得到,创建一个当前线程的map
            //有map则向map中存值
            if (map != null) {
                map.set(this, value);
            } else {
                createMap(t, value);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ThreadLocal的hash

    ThreadLocalMap类似hashmap,但是所使用的hash函数、碰撞处理等方法大不相同

    碰撞处理使用动态寻址法

    ThreadLocalMap中存储的是entry,这个是ThreadLocalMap的内部类,它是一个ThreadLocal类型的弱引用,在map中充当键的位置

    在ThreadLocalMap.set()方法的最后,如果执行完启发式清理工作后,未清理到任何数据,且当前散列数组中Entry的数量已经达到了列表的扩容阈值(len*2/3),就开始执行rehash()逻辑,也就是扩容处理

    内存泄漏

    让一个虚引用当值主要是为了防止内存泄漏,当ThreadLocal需要被回收的时候,如果在map中的键是强引用,那么这个对象是无法被回收掉的

            static class Entry extends WeakReference<ThreadLocal<?>> {
                /** The value associated with this ThreadLocal. */
                Object value;
    
                Entry(ThreadLocal<?> k, Object v) {
                    super(k);
                    value = v;
                }
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ThreadLocal需要我们解决的的内存泄漏问题是下面这种

    因为ThreadLocalMap的键为弱引用,值为强引用,每次GC后,键的指向都为null(因为ThreadLoacl被回收掉了,但是这个弱引用指针并没有被回收),值的指向对象依然没有被回收,产生了OOM问题

    解决办法是在使用完毕后调用remove方法手动清除

    过期删除处理

    当Map中的键指向null的时候代表这个数据过期了,需要被回收掉,ThreadLocal提供了俩种过期删除策略

    1,探测式清理操作
    2,启发式清理

  • 相关阅读:
    相机通用类之LMI激光三角相机(3D),软触发硬触发(飞拍),并输出halcon格式对象
    MyBatis完成CRUD 详细细节内容
    华为机试练习题:HJ51 输出单向链表中倒数第k个结点
    内网安装redis+部署redis-cluster集群
    git push常用操作(亲测自用)
    iphone14到手了?你还需要一个专职管家!
    Feign(替代RestTemplate)远程调用
    【PyTorch实战演练】AlexNet网络模型构建并使用Cifar10数据集进行批量训练(附代码)
    JetBrains WebStorm 2024 mac/win版:效率至上,编码无忧
    设计模式学习笔记(十九)观察者模式及应用场景
  • 原文地址:https://blog.csdn.net/sekever/article/details/126752016
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号