一份通俗易懂的ThreadLocal笔记

ThreadLocal的定义

  • ThreadLocal通过为每一个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。
  • 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立的改变自己的副本,而不会影响其他线程所对应的副本。
  • 在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的key为线程对象,value为对应的线程的变量副本。

为什么要用ThreadLoacal

Thread类中有个属性threadLocals,这个参数包含着线程的所有成员变量。我们发现Thread并没有提供成员变量threadLocals的设置与访问的方法,那么每个线程的实例threadLocals参数我们如何操作?这时候就需要用ThreadLocal来实现了。

总结来说:ThreadLocal是线程Thread中属性ThreadLocals的管理者。

抽象比喻如下:
在这里插入图片描述
1.每个人都有一张银行卡。
2.每个人每张卡都有一定的余额。
3.每个人获取银行卡余额都必须通过该银行的管理系统。
4.每个人都只能获取自己卡持有的余额信息,其他的人不可以访问。

在这里插入图片描述
映射到ThreadLocal:
1.card类似于Thread;
2.card余额属性,卡号属性等类似于ThreadLocal内部属性集合threadLocals;
3.cardManager类似于ThreadLocal管理类。

ThreadLocal的实现机制

  • 每个线程都拥有一个ThreadLocalMap对象。
  • 每一个ThreadLocal对象有一个创建时生成的唯一的HashCode,即nextHashCode(),通过取模确定所在位置。
  • 访问一个ThreadLocal变量的值,即是查找ThreadLocalMap中对应的键值对,即key为该
    ThreadLocal的键值对;
  • 由于一个ThreadLocalMap可以拥有多个ThreadLocal,推到可得一个线程可拥有多个ThreadLocal。

ThreadLocal的内存泄漏

首先补充一个知识点:
在这里插入图片描述
由于ThreadLocalMap中的entry中的key是弱引用,当每次GC时JVM会主动将无用的弱引用回收掉,因此ThreadLocal外部没有强引用依赖时,就会被自动回收,这样就可能造成ThreadLocal被回收时,相当于将Map中的key设置为null,但问题是该key对应的Entry和value并不会主动被GC回收。

当Entry和value未被主动回收时,除非当前线程死亡,否则线程对于Entry的强引用会一直存在,从而导致内存泄漏。

解决方法:
ThreadLocal使用后务必调用remove方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值