ThreadLocal的使用及原理

1、使用场景

(1)每一个线程需要一个独享的对象(通常是工具类,如SimpleDateFormate)

代码实现1:将SimpleDateFormat作为静态变量,多个线程之间共用,由于SimpleDteFormat是线程不安全的所以会出错,打印出相同的时间;如果在format()前加上锁会使得效率变的非常低。

 

 

代码实现2:

每次都创建一个SimpleDateFormat对象,这样会创建1000个对象,造成很大的浪费

 

代码实现3:

使用ThreadLocal并覆盖初始化方法,每个线程拥有一个独立的SimpleDateFormat对象,能保证线程安全,且只需要创建10个这种对象。

(2)每个线程要保存全局的变量,方便在多个方法能够直接使用,而不需要反复的传参。

(比如拦截器中获取用户的信息将其保存,后续的方法就能直接拿到用户信息)

 

 运行结果:

 2、ThreadLocal原理:

(1)每个线程都会持有一个线程独占的ThreadLocalMap

(2)ThreadLocalMap是一个键值对集合,可以保存多个ThreadLocal,其中的key是ThreadLocal对象(如例子中的threadLocal所指向的对象),而value是正在的保存的对象(如下面例子中的User对象)

 (3)ThreadLocal的get()方法会先去当前线程的ThreadLocalMap中以ThreadLocal对象为key寻找对应的值,如果找不到,就会返回innitValue()运行的结果。

例:

第一次能正常输出,而后ThreadLocal对象变了,在线程中的ThreadLoacalMap中以改变后的ThreadLocal对象去获取对应的User对象就会获取到空的值

 

 3、重要方法及源码

(1)get

获取当前线程的ThreadLocalMap,并以当前对象(ThreadLocal对象)为key去获取值;如果未获取到则从通过初始化函数innitialValue()获取,并将其加入到线程的ThreadLocalMap中。

 

 (2)set:

将键值对<ThreadLocal对象,真正的内容>插入到当前线程的ThreadLocalMap中,如果当前线程的ThreadLocalMap对象为空就先创建然后再插入。

 (3)remove

 4、使用ThredLocal注意点:

(1)Threadlocal使用完成之后要主动的调用remove()方法,防止内存泄露的发生。

(2)调用set()方法时,不应该传入一个静态变量,否则可能会多个线程对其进行修改,存在线程安全问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值