前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ThreadLocal概述

ThreadLocal概述

作者头像
Coder的技术之路
发布2021-05-14 14:13:50
2400
发布2021-05-14 14:13:50
举报
文章被收录于专栏:Coder的技术之路

ThreadLocal 是解决多线程并发问题时一个常用的且有效的方法。

有的人说ThreadLocal的目的是为了解决多线程访问资源时的共享问题,也有的人反对这种说法,认为ThreadLocal是为了保存线程上下文。

众说纷纭,其实,我觉得没有必要非要给出一种什么样的确定说法,我们的目的是要理解ThreadLocal原理,理解其工作场景和适用问题,最终为我们所用,这就够了。

1.适用场景

ThreadLocal 适用在,多线程所使用的资源属于同一类型资源,且没有全局一致的约束的一类问题。

举个简单的例子:

多数据源配置。当读库和写库的数据源配置不一样时(多么c*蛋的场景),就需要我们在适当的时候动态的去切换数据源。

首先创建一个 ThreadLocal ,重写初始化value的方法,让其默认返回一个数据源类型,然后就是适时的运用,如下:

最后,如果是spring程序,就可以在配置文件中配置两个不同数据源,然后使用AOP,在使用之前动态切换不同的数据源。

其实,其他的ThreadLocal的运用例子也都大同小异。

我们注意到,ThreadLocal所涉及的资源,只是属于同一类,比如上面例子中的 读写标示,而不是全局唯一的共享资源。

我们要做的是为每个线程新建一个独享资源,而不是解决共享资源的互斥访问。

2.工作原理

使用ThreadLocal所涉及的最重要的四个方法,在上例中已经都展示了,就是 initialValue 、set 、get 、remove。我们来分别看下这些方法:

ThreadLocalMap 是Thread的一个属性,为每个Thread对象独有,当get时,取的是当前线程自己的Map。当map不存在时,则调用setInitialValue方法:

这里第一次调用了initialValue方法,设置初始值。在createMap方法中,我们也能看到,这个map是new出来的新的属性。而set方法和上述方法类似,也是在map不存在时,调用了createMap方法。

我们可以看到,在向map中设置值的时候,是 map.set(this , value);

这里的this 当然是ThreadLocal本身,由此可见,thread的map中,存储的 键-值 对,其实是以ThreadLocal自身为键 , value 为值的。

3. ThreadLocalMap

这样做有什么好处呢? 那我们就要从ThreadLocalMap 这个对象来看了。

我们看这个类 ,会发现了一个很重要的父类:WeakReference,这代表,其实ThreadLocalMap这个类,不是直接用ThreadLocal本身作为key,而是以ThreadLocal的弱引用作为key 的。

这样,在Threadlocal在别的地方没有强引用的时候,就会直接被GC,节省内存。

4. 内存溢出

这里其实有一个潜在的危险,就是内存泄露,当Threadlocal 被回收之后,以此ThreadLocal的弱引用为key的value,还会存在于map中,但是,其对应的key已经变成了null 。

虽然ThreadLocalMap,在get .set的时候,做了优化,会对null key的value进行删除,但是,如果一直没有调用get set 就会出现内存溢出,因为value 一直存在于内存,而不被引用。

所以,我们要在决定不使用ThreadLocal的时候,手动的调用remove方法,将其相关的东东全部删掉,以免产生溢出。

其实,我们一般使用的时候,总是将其创建为 private static 类型的,这样,会让其一直存与内存,不会被GC回收,防止溢出。

5.碰撞避免

这里还有一个比较有意思的地方,就是一个特殊的哈希码的使用,

代码语言:javascript
复制
private static final int HASH_INCREMENT = 0x61c88647;

神奇的哈希码,可以极大限度的避免冲突(主要是在多个ThreadLocal 对象时使用)

具体的原理涉及斐波那契散列法以及黄金分割,反正我是不会,还需要再多深入研究一下子,等之后细说。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-02-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coder的技术之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档