当前位置: 首页 > news >正文

ThreadLocal-共享变量

为什么说ThreadLocal是共享变量?缓存的对象是如何隔离的呢?

        并发环境下,在类声明local,每个线程用的都是同一个local,故local对于多线程来说,是共享的。.set()的内部源码是这样的,先获取到当前线程,通过当前线程获取到属于当前线程的ThreadLocalMap,每个entry的key是this(当前local对象),value是缓存的对象。对于每个线程来说,都有各自的ThreadLocalMap,每个ThreadLocalMap是相互隔离的。

ThreadLocal有什么应用场景?

        1、缓存事务。并发环境,每个线程的事务缓存在各自的ThreadLocalMap的value中。

        2、缓存线程不安全的对象,如SimpleDateFormat,日期格式化对象。

        3、缓存Servlet。Servlet是单例的,单例意味着线程不安全,每个请求都有各自的Servlet(包括HttpServletRequest和HttpServletResponse和HttpSession)。使用ThreadLocal保证单例对象的线程安全。

        注意:单例意味着该对象线程不安全。

使用ThreadLocal有什么问题?怎么解决?

        使用线程池,核心线程数是10个,线程全部执行完毕,10个线程不会销毁。线程不回收,entry也不会回收,从而导致内存泄漏。

        注意:heap中的entry中的object是强引用,不会被gc回收。强引用不会被gc回收,必须手动销毁。

        local.get()获取缓存的数据,也就是说,缓存对象使用完之后,我们可以手动清除,local.remove(),完美的解决了ThreadLocal内存泄漏问题。

说说ThreadLocal底层的结构。

        一个线程下面可以new多个ThreadLocal对象,每个对象分别指向当前线程的ThreadLocalMap,ThreadLocalMap存储n个entry,每个entry的key和value分别是this(调用set()的当前threadLocal实例)和object(自定义类实例)。

经历过具体的有ThreadLocal导致的内存泄漏问题么?

        引起内存泄漏问题的因素有两个:1、堆内存的初始大小和最大大小。2、缓存对象存储的数据的最大容量。

        缓存对象中定义了一个字节数据,byte[1024*1024],也就是1M,创建一个核心线程数为30的线程池,使用excute将线程的状态修改为running,循环创建30个线程,共计30个ThreadLocalMap,每个map存储了一个对象,共计30M,而我们jvm堆内存设计的初始容量和最大容量是25M,循环到第26次的时候,内存会泄漏。

        


http://www.mrgr.cn/news/49366.html

相关文章:

  • 【微服务】springboot远程docker进行debug调试使用详解
  • 为什么Python代码需要遵守Pythonic风格?
  • MarsCode--大数和距离【中等】
  • 基于Android的小型冷库管理系统(论文+源码)-kaic
  • 第二讲、C语言的常量和变量
  • 双向广搜 [NOIP2002 提高组] 字串变换————洛谷p1032
  • 基于单片机的 16 键多功能电子琴硬件设计
  • types.MethodType
  • 使用dotnet-counters和dotnet-dump 分析.NET Core 项目内存占用问题
  • Nodejs+Vue菜鸟驿站仓库管理系统的设计与实现 (论文+源码)-kaic
  • 使用 Python 爬虫批量下载百度图片的详细教程
  • C++:模拟stack、queue
  • 【机器学习】深入浅出讲解贝叶斯分类算法
  • 2024年OpenAI开发者大会:开拓AI新时代
  • finebi的20个面试题
  • 初识C语言:数据类型、运算符与表达式
  • Python使用pip安装install模块时指定默认源以及FastApi自定义接口文档/docs中的静态资源文件
  • Edge TTS
  • 架构设计笔记-15-面向服务架构设计理论与实践
  • 【WPF】中ListBox的ListBox选项的选中状态在弹出MessageBox后失效的解决办法