首页 > 其他分享 >ThreadLocal

ThreadLocal

时间:2024-08-23 22:37:21浏览次数:9  
标签:Thread ThreadLocalMap value ThreadLocal 线程 引用

先说结论

一个Thread对应一个ThreadLocalMap,一个ThreadLocalMap可保存多个ThreadLocal为键的键值对,值为需要线程共享的数据,而且多个线程可共用一个ThreadLocal对象,在web项目中多有这样的设计。

源码分析

Thread中有一个ThreadLocalMap类型的属性threadlocals,ThreadLocalMap是ThreadLocal的一个内部类。

1.ThreadLocal的set方法




先获取当前线程t,再执行getMap(t)



其实就是获取t.threadLocals,若此时getMap(t)为空,则执行createMap(this,value)



若为空,则创建ThreadMap对象并给当前Thread的threadLocals属性赋值,并在ThreadLocalMap中放入一对键值对,其中键为当前调用方法的ThreaadLocal对象(this),值为set方法传入的value。
若非空,则直接在该线程对应的ThreadLocalMap中放入该键值对即可。

2.ThreadLocal的get方法




与set方法类似,先获取当前Thread对应的ThreadLocalMap,再通过ThreadLocal实例(this)获取所需值。

3.remove方法

4.ThreadLocal的并发性

由于每一个ThreadLocal都对应了一个ThreadLocalMap,也就是说每一个线程都持有一份数据副本,也就不存在数据的并发操作。
Thread中还有一个ThreadLocalMap类型的属性inheritableThreadLocals。在new Thread()时,在构造方法里会把父线程中的inheritableThreadLocals的ThreadLocalMap内容复制给当前子线程的inheritableThreadLocals,也就是说子线程会继承父线程中的inheritableThreadLocals对应的ThreadLocalMap,而且是复制一份,子线程中的ThreadLocalMap和父线程中的ThreadLocalMap中的内容一开始是一样的,但是后续的修改将互不影响。

5.ThreadLocal的内存泄漏问题

ThreadLocaMap中,key对ThreadLocal的引用时弱引用。


5.1 为什么要对ThreadLocal使用弱引用?

因为ThreadLocal就是做同线程数据共享的,若ThreadLocal中不存在对象引用时,ThreadLocal也应该被回收,而由于设计的引用链,Thread引用ThreadLocalMap,ThreadLocalMap中的key又引用ThreadLocal,使得ThreadLocal不会被回收。而弱引用的特点为当对象只有弱引用存在时,该对象可以被gc回收。所以对Thread Local使用弱引用能解决此问题。

5.2 引发的内存泄漏问题

ThreadLocal为弱引用,这样就会导致ThreadLocalMap.Entry的key为null,而value是强引用,那么会导致value引用的对象只有在Thread销毁时才会被释放,ThreadLocalMap中也永远存在一个value非空的永远不会被访问到的Entry,引发了内存的泄漏。

  • 解决方法:
    程序员手动执行remove方法。

5.3 为什么不把value设置为弱引用?

避免外部持有key的引用来查询value,而value却被回收的情况。

标签:Thread,ThreadLocalMap,value,ThreadLocal,线程,引用
From: https://www.cnblogs.com/zlzw1/p/18377198

相关文章

  • 什么?!90%的ThreadLocal都在滥用或错用!
    最近在看一个系统代码时,发现系统里面在使用到了ThreadLocal,乍一看,好像很高级的样子。我再仔细一看,这个场景并不会存在线程安全问题,完全只是在一个方法中传参使用的啊!(震惊)难道是我水平太低,看不懂这个高级用法?经过和架构师请教和确认,这完全就是一个ThreadLocal滥用的典型案......
  • 什么?!90%的ThreadLocal都在滥用或错用!
    最近在看一个系统代码时,发现系统里面在使用到了ThreadLocal,乍一看,好像很高级的样子。我再仔细一看,这个场景并不会存在线程安全问题,完全只是在一个方法中传参使用的啊!(震惊)难道是我水平太低,看不懂这个高级用法?经过和架构师请教和确认,这完全就是一个ThreadLocal滥用的典型案例啊!......
  • ThreadLocal ThreadLocalUtil
    ThreadLocalUtil.javapublicclassThreadLocalUtil{staticfinalThreadLocalTHREAD_LOCAL=newThreadLocal();publicstatic<T>Tget(){return(T)THREAD_LOCAL.get();}publicstaticvoidset(Objectvalue){TH......
  • 【Java 并发编程】(四) ThreadLocal 源码解读
     介绍每个Thread对象,内部有一个ThreadLocalMapthreadLocals,这是一个哈希表,底层是一个Node[]table;当在某个线程中调用ThreadLocal的set方法时,会使用Thread.currentThread获取当前先线程的thread对象,然后将ThreadLocal对象作为key,将set方法的参数作为value......
  • ThreadLocal 家族:ThreadLocal、InheritableThreadLocal 与 TransmittableThreadLocal
    在当今的Java多线程编程领域,ThreadLocal及其相关的扩展InheritableThreadLocal和TransmittableThreadLocal宛如三把利剑,为我们在处理线程本地数据时提供了强大而灵活的工具。深入理解它们各自的特点、差异以及适用场景,对于我们编写出高效、可靠且稳定的多线程代码具有至......
  • ThreadLocal源码解析
    ThreadLocal有内部类ThreadLocalMap,ThreadLocalMap是ThreadLocal的核心1.每个线程下的有一个ThreadLocalMapstaticclassThreadLocalMap{staticclassEntryextendsWeakReference<ThreadLocal<?>>{Objectvalue;Entry(ThreadLocal<?>k,Ob......
  • Java 中的线程本地存储(ThreadLocal)机制介绍
    Java中的ThreadLocal是一个用于实现线程本地存储(ThreadLocalStorage,TLS)的机制。它可以为每个线程提供独立的变量副本,使得一个线程中的变量不受其他线程中的变量的影响。ThreadLocal通常用于在多线程环境下避免线程之间共享数据,从而实现线程安全。一、基本用法ThreadLoca......
  • 深入理解 ThreadLocal:机制、原理与实践
    引言ThreadLocal是Java中一个非常重要的工具,广泛用于解决多线程环境下变量共享的问题。然而,ThreadLocal的使用也可能带来一些隐患,尤其是在结合线程池的场景中,可能导致数据混乱。本文将深入探讨ThreadLocal的工作机制及其可能带来的问题,并给出相应的解决方案。一、Thr......
  • [Java并发]ThreadLocal补充
    ThreadLocal缺点及解决方案每个Thread上都有一个threadLocals属性,它是一个ThreadLocalMap,里面存放着一个Entry数组,key是ThreadLocal类型的弱引用,value是对用的值。所有的操作都是基于这个ThreadLocalMap操作的。但是它有一个局限性,就是不能在父子线程之间传递。即在子线程中无......
  • ThreadLocal
    为什么多线程需要加锁1.ThreadLocal的介绍从Java官方文档中的描述:ThreadLocal类用来提供线程内部的局部变量。这种变量子在多线程环境下访问(通过get和set方法)时能保证各个线程的变量相对独立于其他线程内的变量,ThreadLocal实例通常来说都是privatestatic类型的,用于关联......