ThreadLocal

简介

1. ThreadLocal是多线程中用来保存某个线程独有的操作;

2. ThreadLocal中的内容不能被其他Thread访问、不需要返回到公用内存;

API

1. get() 和 set() 方法是用来获取内容和存储内容的方法;

2. initalValue() :用来初始化变量的方法,在创建每一个ThreadLocal变量时,我们最好将其初始化为我们认为的初始值,不然他默认初始化值为NULL,后续操作时可能会出现问题;

ThreadLocal<Integer> data = new ThreadLocal<Integer>(){
@Override
protected Integer initalValue(){
        
return 0;
 }

}

3. withInitial()静态方法:使用Java8新特性函数式编程,用于创建ThreadLocal变量并且将其初始化

ThreadLocal<Integer> data = ThreadLocal.withInitial(() ->0);

源码分析 

底层源码中:ThreadLocalMap是ThreadLocal的静态内部类,并且Thread可以通过ThreadLocal访问ThreadLocalMap

get()方法

  • 首次调用get()时,会调用 return setInitialValue()方法

从上述可得出 ThreadLocal、ThreadLocalMap、Thread三者的关系:

Thread对象维护着一个ThreadLocalMap的引用,而我们存储的数据就是放在ThreadLocalMap中的Entry对象中

ThreadLocal中的弱引用以及内存泄漏问题

 源码

为什么要使用弱引用?

 当方法t1执行完时,t1对ThreadLocal的强引用就不存在了,此时若ThreadLocal 与 ThreadLocalMap中的Entry是强引用关系,那么此时 ThreadLocal 和 Entry都不可以被回收(因为两者间存在强引用关系)此时变造成了内存泄漏,但如果是弱引用关系,如果外部没有强引用引用ThreadLocal则在内存不够时系统gc也会将其进行回收。

内存泄漏

除了上面说的内存泄漏外,还有可能当t1方法结束,ThreadLocal被回收,而Entry中的key是弱引用指向ThreadLocal的(key是ThreadLocal),此时 key被回收,但value却仍然没被回收,此时的key为null,无法调用取得value(这些key为null的Entry的value就会一直存在一条强引用链);

因此弱引用不能一定保证内存不泄露,我们要在用完某个ThreadLocal对象后,手动调用remove方法来删除他;

使用建议

1. 使用 try finally,在finally中调用remove()方法,在阿里巴巴Java开发手册中有:

2. 用static 修饰ThreadLocal对象

3. 在使用TheadLocal对象前,先将其初始化操作;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值