ThreadLocal的原理及使用-SimpDateFormat线程不安全问题

本文探讨了在工作中遇到的线程不安全问题,特别关注SimpDateFormat,并介绍了如何通过ThreadLocal解决。作者讲解了ThreadLocal的工作原理,展示了如何使用和潜在的问题,如内存泄漏。
摘要由CSDN通过智能技术生成

在日常工作的时候,编写了一个计算工作日的工具类,当时直接定义了static fina的一个SimpDateFormat,一开始没有感到哪里不对,后来想到这个时间的格式化类是线程不安全的。

SimpDateFormat线程不安全的原因:

calendar变量共享,在进行format等操作的时候,会对该对象赋值和操作,当多条线程同时访问的时候就出现了安全问题。当然要解决这个问题可以使用多种方式,可以使用java8中的LocalDateTime、LocalDate、LocalTime等时间类,或者使用ThreadLocal来实现。

我这里考虑到可能项目可能会使用java7,所以使用了ThreadLocal来做线程安全问题。所以先来说一下ThreadLocal。

1.原理

ThreadLocal是线程独享的变量,在不同的线程中有不同的副本。因为每个Thread内都存在自己的实例吗,所以Thread之间不共享该变量。ThreadLocal的实例副本通常会在线程结束时回收(注:在GC的时候如果没有外部强引用的话容易造成内存泄漏),

ThreadLocal内部实现了一个ThreadLocalMap静态内部类来储存变量,所有的get,set,remove等方法都是在操作该静态内部类的方法。

 

2.使用

使用的话比较简单,按自己需要决定是否实现初始化方法,然后通过get,set方法来实现数据的获取和赋值。例如:

当然,在最后使用完成以后,记得调用remove方法,清空当前线程的数据。

 

3.问题

ThreadLocalMap中的Key为ThreadLocal变量的弱引用(关于弱引用和强引用可以百度了解下),代码如下图:

key为ThreadLocal的弱引用,在gc的时候如果没有外部的强引用就会被回收,但是value为私有对象(强引用),就会造成value指向的对象无法回收,进而内存泄漏。

如果私用了线程池(线程会复用),那么如果数据没有remove的话,会造成数据的重复使用(脏数据)。

总的来说,出现以上问题都可以使用remove来解决,当然脏数据问题也可以在线程开始前调用set方法来设置初始值。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值