侧边栏壁纸
博主头像
IT充电站博主等级

看过故人终场戏,淡抹最适宜

  • 累计撰写 48 篇文章
  • 累计创建 13 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

ThreadLocal的结构和用法

陈汉林
2024-05-24 / 0 评论 / 0 点赞 / 29 阅读 / 3876 字

结构

ThreadLocal 类提供了一个简单的接口,主要有以下几个方法:

  • void set(T value): 设置当前线程的局部变量的值。

  • T get(): 返回当前线程所对应的局部变量的值。

  • T initialValue(): 如果线程还没有局部变量的副本,则像下面这样提供一个初始化值。

  • void remove(): 清除当前线程的局部变量副本。

源码结构

public class ThreadLocal<T>{
		
	...
	
    static class ThreadLocalMap{
		private Entry[] table;

		static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }
	}



}

ThreadLocal中用于保存线程的独有变量的数据结构是一个内部类:ThreadLocalMap,是一个K/V结构

key:当前ThreadLocal的对象引用

value:要保存的目标值

内存泄漏的原因

  1. ThreadLocal对象在栈的引用结束后,ThreadLocalMap中的key还是有引用指向了ThreadLocal对象

  2. ThreadLocalMap是当前线程的一个成员变量,它存在一条引用指向Entry对象的value对象,如果当前线程处于线程池的复用状态,那么线程就会一直存活,那么该引用就一直存在。

解决方案

  1. 针对第1点,JDK源码中key的结构是:WeakReference<ThreadLocal<?>>,通过弱引用下次GC时进行回收释放

  2. 针对第2点,在使用完ThreadLocal之后,最好在finally模块进行调用ThreadLocal.remove()方法,下次GC时清理Entry对象

ThreadLocal和ThreadLocalMap

  • ThreadLocal 类本身并不存储线程局部变量的值,它只是用来访问线程局部变量的一个工具。

  • 每个线程(Thread 类的实例)内部维护了一个 ThreadLocalMap。这个映射是线程私有的,用来存储 ThreadLocal 变量的副本。

  • ThreadLocalMap 的键是 ThreadLocal 对象的弱引用(weak reference),而值是线程局部变量的实际值。

ThreadLocalMap结构

  • ThreadLocalMapThreadLocal 类的一个静态内部类。

  • 每个 Thread 对象都有一个 ThreadLocalMap 实例作为其线程局部变量的存储。

  • ThreadLocalset() 方法被调用时,它会访问当前线程的 ThreadLocalMap,并将 ThreadLocal 对象自身作为键(通过 ThreadLocalMapThreadLocalHash 实现),将值作为 ThreadLocalMap 的值存储起来。

为什么值不会互相影响

  • 尽管 threadLocalValue 这个引用在多个线程之间是共享的,但是每个线程通过 threadLocalValue 访问的 ThreadLocalMap 是独立的。

  • 每个线程的 ThreadLocalMapThreadLocal 对象(作为键)是相同的,但是由于 ThreadLocalMap 是线程局部的,因此每个线程实际上访问的是自己的 ThreadLocalMap 实例。

总结

ThreadLocal 的设计确保了每个线程可以访问自己的局部变量副本,即使 ThreadLocal 对象本身是共享的。这是通过在每个线程的 Thread 实例中维护一个独立的 ThreadLocalMap 来实现的。这种设计允许 ThreadLocal 变量在多线程环境中安全地使用,而不必担心数据的并发访问问题。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区