threadlocal使用场景_聊一聊面试常见的ThreadLocal问题

短小而精悍,简单易懂,每天Look一眼,增长技术实力。

先简单描述一下:

ThreadLoal 线程局部变量,同一个 ThreadLocal 所包含的对象,在不同的 Thread 中有不同的副本

  1. Thread 内有自己的实例副本,且该副本只能由当前 Thread 使用
  2. Thread 有自己的实例副本,不存在多线程间共享的问题
  3. ThreadLocal 变量通常被private static修饰,当一个线程结束时,它所使用的所有 ThreadLocal 相对的实例副本都可被回收

总体描述一下使用场景:

  • 每个线程需要有自己单独的实例
  • 实例需要在多个方法中共享,但不希望被多线程共享

举个例子:Java7 中的SimpleDateFormat不是线程安全的,可以用ThreadLocal来解决这个问题

(java8中的DateTimeFormatter是线程安全的)

df90719673e7b7a899ea3fab9c1abe2c.png

谈谈一下内部原理:也就是面试的时候喜欢问的东东

  1. 首先明确一点 ThreadLocal 是一个泛型类,保证可以接受任何类型的对象
  2. ThreadLocal 内部维护了一个 Map 注意下的是 该 Map 不是 HashMap 而是ThreadLocalMap ,它是一个静态内部类
  3. ThreadLocal 方法 get() ,set(),remove()方法其实调用的是内部ThreadLocalMap对应的方法,外面其实是一个引用壳,传递方法引用
  4. 简单Look一下源码加深一下记忆
01acee30996dfc40ed2e79aa0eba785b.png

源码对应的set方法

a79f8f9fa4ed3bcee1e669a7e658440c.png

源码对应的get方法

咱接着谈一下 使用场景注意的地方 内存泄漏 (上面都是常识的话,这里就是使用经验)

  1. ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用(弱引用特点,如果这个对象只存在弱引用,那么在下一次垃圾回收的时候必然会被清理掉)
  2. ThreadLocal 内部的 value 是强引用,不会被清理,这样一来就有可能出现 key 为 null 的 value 也就是此处会有可能造成内存泄漏的情况
  3. ThreadLocal设计维护还是挺不错的,充分考虑到了这一点,在使用set(),get(),remove()方法的时候 内部会做一次扫描检测,如果存在key为null的情况会自动回收

基于以上特点所以在使用的时候规范一下 :避免这种情况的出现要主动调用remove()方法启动内部循环检测,清除无效数据。使用 try-finally 块进行回收,在finally中,主动调用该对象的remvoe()方法。

最后再简单看一下类 ThreadLocalRandom

ThreadLocalRandom使用ThreadLocal的原理,让每个线程内持有一个本地的种子变量,该种子变量只有在使用随机数时候才会被初始化,多线程下计算新种子时候是根据自己线程内维护的种子变量进行更新,从而避免了竞争

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值