ThreadLocal 底层原理如下:



实线是强引用,虚线是弱引用

Thread 持有 ThreadLocal 对象的引用,ThreadLocalMap 是 Thread 的成员变量,它是一个 Map,key 是 ThreadLocal 对象, value 是我们 set 进去的值

和 Map 一样,每一对 key:value 封装成了一个 Entry 对象,它的 key 是虚引用,也就是上图的虚线



这里为什么是虚引用?如果是强引用会发生什么问题?

假设 Entry 是强引用,那么当线程执行完毕后,就会变成下面这样



ThreadLocal 没有被使用,但是也无法被 JVM 回收,导致内存泄漏

如果是虚引用的话,当线程结束后,ThreadLocal 会被 JVM 回收,如下所示



这就引出了为什么我们使用完 ThreadLocal 后需要将 remove 操作

如果不进行 remove ,会堆积很多 null:value 的 Entry 导致内存泄漏

顺带提一下 Java 中的四种引用:

  • 强引用:new 出来的都是强引用类型,只要当它没有引用时才会被 JVM 回收
  • 软引用:在内存足够的情况下,即便没有引用也不会被回收,内存不足时,就算有引用也会被回收
  • 弱引用:只要发生 GC,对象就会被回收
  • 虚引用:一般我们可以不用太关注,它是记录引用的引用

关于ThreadLocal最直白的解释的更多相关文章

  1. [转]ThreadLocal使用

    引言 ThreadLocal的官方API解释为: “该类提供了线程局部 (thread-local) 变量.这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线 ...

  2. Java ThreadLocal 使用详解

    ThreadLocal的官方API解释为: "该类提供了线程局部 (thread-local) 变量.这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每 ...

  3. java高并发系列 - 第24天:ThreadLocal、InheritableThreadLocal(通俗易懂)

    java高并发系列第24篇文章. 环境:jdk1.8. 本文内容 需要解决的问题 介绍ThreadLocal 介绍InheritableThreadLocal 需要解决的问题 我们还是以解决问题的方式 ...

  4. OpenCV击中击不中HMTxingt变换最容易理解的解释

    OpenCV击中击不中变换是几个形态变换中相对比较拗口.不容易理解的,给初学者理解带来了很多困难,虽然网上也有许多的公开资料,原理和算法基本上介绍比较清晰,但是是要OpenCV进行形态变换大多还是说得 ...

  5. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  6. 移动端全兼容的flexbox速成班

    说起flexbox,都算是件陈年旧事了,它是2009年W3C提出的一种全新的可伸缩的CSS布局方式.依赖flexbox,我们可以更简单,高效的完成可伸缩式页面的布局. 业界与flexbox的相关教程文 ...

  7. INFO: task java:27465 blocked for more than 120 seconds不一定是cache太大的问题

    这几天,老有几个环境在中午收盘后者下午收盘后那一会儿,系统打不开,然后过了一会儿,进程就消失不见了,查看了下/var/log/message,有如下信息: Dec 12 11:35:38 iZ23nn ...

  8. DDD:建模原语 之 四象图(转载的神文)

    “模型.状态和行为特征.场景”和“四象图”,建模观的命名与立象. 建模原语:四象图 作者:achieveidea@gmail.com 命名:模型.结构特征.行为特征.场景(及其规约). 释义:模型,描 ...

  9. Android IOS WebRTC 音视频开发总结(四九)-- ffmpeg介绍

    本文主要介绍ffmpeg,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,个人微信公众号blacker,更多详见www.rtc.help 说明: ps1:如果直接从webrtc开始学 ...

  10. ASP.NET不拖控件教程(1)-认识JSON

    我讲讲脱离ASP.NET控件必备的一步,JSON和使用JQuery获取JSON吧! 高手跳过,写给学习中的人的.这篇帖子是假设你会使用JQuery(JQ这么普及,应该不至少没学过吧!真没学过以后再开帖 ...

随机推荐

  1. ContOS7搭建RAID-0磁盘阵列

    RAID-0条带数据: 优点:2块硬盘同时在写数据,而且各写各的不影响,速度较快:性能提升2倍(理论): 缺点:服务器硬盘特别容易损坏,一点损坏一个,其余不能用:没有容错性:服务器用的不多,都是配合使 ...

  2. redis 简单整理——bitmaps[十二]

    前言 简单介绍一下bitmaps这个东西. 正文 我们都知道bitmaps 翻译过来就是二进制. 那么二进制可以存一些什么呢? 图片.视频,还可也存些什么呢? 现代计算机用二进制(位)作为信息的基础单 ...

  3. MMDeploy部署实战系列【第五章】:Windows下Release x64编译mmdeploy(C++),对TensorRT模型进行推理

    MMDeploy部署实战系列[第五章]:Windows下Release x64编译mmdeploy(C++),对TensorRT模型进行推理 这个系列是一个随笔,是我走过的一些路,有些地方可能不太完善 ...

  4. log4j2 lookup漏洞修复方法

    2021.12.10凌晨,Apache Log4j远程代码执行漏洞细节被公开,参考链接:https://unit42.paloaltonetworks.com/apache-log4j-vulnera ...

  5. 《C# in depth》第5章C#5.0中的更改(十二)——指针和非安全编码

    指针类型是一种C# 5.0 中引入的不安全代码特性,它允许程序员直接访问内存地址,以及使用指向变量和对象的指针.指针类型可以帮助程序员处理一些高性能场景,例如在大型数组中查找数据. 指针类型需要使用 ...

  6. 力扣586(MySQL)-订单最多的客户(简单)

    题目: 编写一个SQL查询,为下了 最多订单 的客户查找 customer_number . 测试用例生成后, 恰好有一个客户 比任何其他客户下了更多的订单. 查询结果格式如下所示. 进阶: 如果有多 ...

  7. 力扣13(java)-罗马数字转整数(简单)

    题目: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II ,即为两个并列的 1 ...

  8. MySQL实战—更新过程

    和查询流程不同的是,更新流程涉及两个重要的日志模块:redo log(重做日志)和 binlog(二进制日志). redo log redo log通常是物理日志,记录的是数据页的物理修改,而不是某一 ...

  9. 详解 Flink 容器化环境下的 OOM Killed

    简介: 本文将解析 JVM 和 Flink 的内存模型,并总结在工作中遇到和在社区交流中了解到的造成 Flink 内存使用超出容器限制的常见原因.由于 Flink 内存使用与用户代码.部署环境.各种依 ...

  10. 在 Dubbo3.0 上服务治理的实践

    ​简介: Dubbo 3.0 是在云原生背景下诞生的,使用 Dubbo 构建的微服务遵循云原生思想,能更好的复用底层云原生基础设施.贴合云原生微服务架构. Dubbo3.0 介绍 作者 | 十眠 自从 ...