再次深入探究ThreadLocal原理及其使用方法,以此记录

本文深入探讨了ThreadLocal的工作原理,解释了其如何通过在每个线程中创建独立的线程共享变量来解决线程安全问题,同时分析了set、get、remove方法的实现,并讨论了如何避免内存泄漏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

再次深入探究ThreadLocal,以此记录。

为什么说ThreadLocal叫做线程本地变量,因为ThreadLocal在每个线程中对该变量会创建一个线程共享变量,即每个线程内部都会有一个该变量,且在线程内部任何地方都可以使用,线程之间互不影响,这样一来就不存在线程安全问题,也不会严重影响程序执行性能。

 

使用ThreadLocal不外乎3个方法:

threadLocal.set()

threadLocal.get()

threadLocal.remove()

顾名思义,分别是设置、获取、移除当前线程中共享变量的值。

话不多说,直接上源码:

get()方法

跟入getMap(t)方法一探究竟

threadLocals

实际上就是一个ThreadLocalMap对象。

ThreadLocalMap其实就是在ThreadLocal中的一个内部类

setInitialValue()

createMap()

new一个ThreadLocalMap对象返回

set()和remove()方法

 

至此,真相大白。

真正存储线程共享变量的地方是当前线程对象Thread的成员变量threadLocals,类型是ThreadLocal.ThreadLocalMap,k:ThreadLocal变量,v:线程共享变量

 

一开始,当前线程中的threadLocals为null,调用set()时,会对其中的threadLocals进行初始化,k就是ThreadLocal,v就是需要存放的线程共享变量

当需要的时候就可以从threadLocals中获取到。

 

总结:

  1. 之所以说ThreadLocal线程安全,是因为所需要存储的线程共享变量,都是存放在当前线程的threadLocals中。
  2. 选择ThreadLocal作为threadLocals的key,是因为每个线程中可有多个threadLocal变量
  3. 在进行get之前,必须先set,否则会报空指针异常;

 

使用ThreadLocal的好处:

  1. 在多线程的环境中,保证当前线程的线程共享变量不被其他线程干扰,即不存在线程安全问题。
  2. 当线程死去时,threadLocals也就被销毁。
  3. threadLocals的k-v数量由ThreadLocal对象的数量决定,比起Thread数量,ThreadLocal数量较少,性能更好。

关于ThreadLocalMap<ThreadLocal, Object>弱引用问题:

当线程没有结束,但是ThreadLocal已经被回收,则可能导致线程中存在threadLocals的键值对,造成内存泄露。

(ThreadLocal被回收,ThreadLocal关联的线程共享变量还存在)。

虽然ThreadLocal的get,set方法可以清除ThreadLocalMap中key为null的value,但是get,set方法在内存泄露后并不会必然调用。

为了防止弱引用问题(threadLocals键值对没有被即使回收,造成内存泄漏)的出现,我们有两种手段:

1、使用完线程共享变量后,显示调用ThreadLocalMap.remove方法清除线程共享变量;

2、JDK建议ThreadLocal定义为private static,这样ThreadLocal的弱引用问题则不存在了。

 

例子为证:

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值