ThreadLocal原理探究和内存泄漏问题

什么是ThreadLocal

ThreadLocal提供了线程的局部变量,每个线程都可以通过set()和get()来对这个局部变量进行操作,但不会和其他线程的局部变量进行冲突,实现了线程的数据隔离。

应用场景

  • 管理Connection
    在学JDBC的时候,为了方便操作写了一个简单数据库连接池,需要数据库连接池的理由也很简单,频繁创建和关闭Connection是一件非常耗费资源的操作,因此需要创建数据库连接池。
    那么,数据库连接池的连接怎么管理呢??我们交由ThreadLocal来进行管理。为什么交给它来管理呢??ThreadLocal能够实现当前线程的操作都是用同一个Connection,保证了事务!
  • 避免一些参数传递
    每当我访问一个页面的时候,浏览器都会帮我们从硬盘中找到对应的Cookie发送过去。
    浏览器是十分聪明的,不会发送别的网站的Cookie过去,只带当前网站发布过来的Cookie过去
    浏览器就相当于我们的ThreadLocal,它仅仅会发送我们当前浏览器存在的Cookie(ThreadLocal的局部变量),不同的浏览器对Cookie是隔离的
  • 在编写程序中也是一样的:日常中我们要去办理业务可能会有很多地方用到身份证,各类证件,每次我们都要掏出来很麻烦。
    而如果用了ThreadLocal的话,ThreadLocal就相当于一个机构,ThreadLocal机构做了记录你有那么多张证件。用到的时候就不用自己掏了,问机构拿就可以了。

ThreadLocal实现原理

  • set()方法
    在这里插入图片描述
    在这里插入图片描述
    ThreadLocalMap是ThreadLocal的一个内部类。用Entry类来进行存储
    我们的值都是存储到这个Map上的,key是当前ThreadLocal对象!
    如果该Map不存在则初始化一个,否则就从Thread中获取。、每个Thread维护了一个ThreadLocalMap变量。
    ThreadLocalMap是在ThreadLocal中使用内部类来编写的,但对象的引用是在Thread中!
    Thread为每个线程维护了ThreadLocalMap这么一个Map,而ThreadLocalMap的key是LocalThread对象本身,value则是要存储的对象
  • get()方法
    在这里插入图片描述

内存泄漏

  • 内存泄露:不再使用的对象和变量的空间不能被回收。时间久之后会浪费掉大量的内存空间。
  • 强引用:无论任何情况下, 只要强引用关系还存在, 垃圾收集器就永远不会回收掉被引用的对象。
  • 软引用:在系统将要发生内存溢出异常前, 会把这些对象列进回收范围之中进行第二次回收
  • 弱引用:被弱引用关联的对象只能生存到下一次垃圾收集发生为止
  • 虚引用:一个对象是否有虚引用的存在, 完全不会对其生存时间构成影响

在这里插入图片描述

和key是否是强弱引用无关,由于ThreadLocalMap的生命周期跟Thread一样长,如果没有手动删除对应key就会导致内存泄漏。
想要避免内存泄露就要手动remove()掉!

猜你喜欢

转载自blog.csdn.net/AIJXB/article/details/115029956