一个线程安全问题引发的ThreadLocal类探索

背景: 今天在开发项目的时候碰到一个线程安全的问题。具体的情况是这样的,服务是基于dubbo对外提供服务的。所有的请求就是java服务多线程处理的。我写的一个类里面有多个方法需要重复的查询DB来获取数据,使用希望定义一个全局变量来保存,只需要查询一次即可。但是由于是一个静态变量在多线程环境下面是不安全的。所以需要一个办法来让静态变量在线程与线程直接互相独立,互不干扰。后经同事的提醒,可以用ThreadLocal来解决,所以先对这个类进行了一次了解。

探索过程

首先要了解java变量作用域的问题。

静态变量: 线程非安全。静态变量即类变量,位于方法区,为所有对象共享,共享一份内存,一旦静态变量被修改,其他对象均对修改可见,故线程非安全。
实例变量: 单例模式(只有一个对象实例存在)线程非安全,非单例线程安全。实例变量为对象实例私有,在虚拟机的堆中分配,若在系统中只存在一个此对象的实例,在多线程环境下,“犹如”静态变量那样,被某个线程修改后,其他线程对修改均可见,故线程非安全;如果每个线程执行都是在不同的对象中,那对象与对象之间的实例变量的修改将互不影响,故线程安全。
局部变量: 线程安全。每个线程执行时将会把局部变量放在各自栈帧的工作内存中,线程间不共享,故不存在线程安全问题。

这里我使用的是静态变量,多线程下面变量的内存区域是共享的。这就意味着当一个线程给这个变量负责了a下面的逻辑需要这个变量为a才能保证逻辑正确,但是此时另外一个线程将这个变量改成了b。咔~~,程序逻辑就错了。而且这种还不是语法错,还是偶然性的,出问题的时候可能就需要花很多时间来排查问题。


那ThreadLocal是怎么避免这个问题呢.
原理大概是一个线程的map,可以理解为Map<Thread, Map<K, V>>这样的结果,Thread就是线程号了,下面的map就是我们使用存储的值。
详细内容看这里深入剖析ThreadLocal实现原理以及内存泄漏问题
在这篇文章里面同时也引入了另外一个问题,ThreadLocal内存泄露的问题。

ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用来引用它,那么系统 GC 的时候,这个ThreadLocal势必会被回收,这样一来,ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永远无法回收,造成内存泄漏。
其实,ThreadLocalMap的设计中已经考虑到这种情况,也加上了一些防护措施:在ThreadLocal的get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value。

原文链接

顺便去喵了一眼这个博主的博客,才知道他还没有毕业。看看他在大学里面干的事情,再回想自己当年大学里面是浪费了多少时间。多么无知。

最后带一个使用方法吧,看这些博文里面都没有写怎么用

private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
threadLocal.set(100L);
threadLocal.get();
threadLocal.remove();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,341评论 11 349
  • Android Handler机制系列文章整体内容如下: Android Handler机制1之ThreadAnd...
    隔壁老李头阅读 7,665评论 4 30
  • 前言 ThreadLocal很多同学都搞不懂是什么东西,可以用来干嘛。但面试时却又经常问到,所以这次我和大家一起学...
    liangzzz阅读 12,488评论 14 228
  • 原创文章&经验总结&从校招到A厂一路阳光一路沧桑 详情请戳www.codercc.com 1. ThreadLoc...
    你听___阅读 6,759评论 8 19
  • 使用nvm管理node的版本 使用淘宝源可以加快安装速度:http://npm.taobao.org/
    Juude阅读 364评论 0 0