Java - 【ThreadLocal】线程本地变量

ThreadLocal

  • ThreadLocal是什么?是用来干什么的?
  • ThreadLocal和Thread有什么关系?
  • Thread底层是如何实现的(底层原理是什么)?
  • [过渡] → 为什么Entry要继承于Weakness?
  • [过渡] → 为什么ThreadLocal要提供remove()方法?
  • ThreadLocal会造成内存泄漏,你了解吗?
  • 什么是内存泄漏?
  • 举几个Java中内存泄漏的例子

一:ThreadLocal是什么?是用来干什么的?

ThreadLocal全称线程本地变量,ThreadLocal可以使得每个线程操作属于自己的TL不是共享TL
Java - 【ThreadLocal】线程本地变量

二:ThreadLocal和Thread有什么关系?

ThreadLocal的set方法与get方法通过操作Thread类中的threadLocals(ThreadLocal.ThreadLocalMap)成员实现;

Java - 【ThreadLocal】线程本地变量Java - 【ThreadLocal】线程本地变量

三:ThreadLocal底层是如何实现的?

ThreadLocal对象提供了三个主要的方法:

  • set(T value)
  • get()
  • remove()

1> set(T value) + get( )
Java - 【ThreadLocal】线程本地变量
接下来查看ThreadLocalMap是什么:
Java - 【ThreadLocal】线程本地变量现在抽象出set()、get()方法的执行逻辑:

Java - 【ThreadLocal】线程本地变量

2> remove()

移除ThreadLocal在当前线程内的Entry
Java - 【ThreadLocal】线程本地变量Java - 【ThreadLocal】线程本地变量

四:ThreadLocal会造成内存泄漏,你了解吗?

  • 为什么Entry要继承于Weakness?
    • 如果全局变量ThreadLocal tl = null,那么内存中的ThreadLocal由于有Entry中的key一直指向,将会永远不会被垃圾回收;
    • 为了防止这种情况导致的内存泄漏,将Entry继承于Weakness,Entry中的key值使用Weakness的构造函数初始化;
  • 为什么ThreadLocal另一个会因为程序员操作不当实际存在的内存泄漏在什么地方?
    • 上方Entry中的key是虚引用类型,但是Entry的value不是虚引用,value所指向的对象仍然有可能会造成内存泄漏;
    • 所以ThreadLocal提供了remove方法用于手动清除整个Entry。

五:什么是内存泄漏?还在哪些地方能够体现?

  • 内存泄漏(MemoryLeak):部分对象不再使用,但是因为某些原因不能被GC回收,一直占用内存的现象;
  • 其他案例finalize的使用不当