欢迎您来到,李雷博客 | PHP博客        登录  |  注册

ThreadLocal的set方法原理是什么

更新:2023-02-26 08:25:53
人气:266
来源:互联网转载
A+

这篇文章主要介绍了ThreadLocal的set方法原理是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇ThreadLocal的set方法原理是什么文章都会有所收获,下面我们一起来看看吧。

前沿知识

  • ThreadLocal
    存储线程变量,使用
    set
    方法设置变量,使用
    get
    方法获取变量

  • 线程隔离的实现是每个

    Thread
    类有一个类型为
    ThreadLocal.ThreadLocalMap
    的实例变量
    threadLocals
    。如下图所示,
    ThreadLocalMap
    内部有一个
    Entry
    数组,每个
    Entry
    的key是
    ThreadLocal
    ,也就是
    referent
    对象,value是设置的值;该类的size变量记录当前数组使用容量;threshold变量记录阈值,默认总容量的三分之二,初始是10

ThreadLocal的set方法原理是什么

  • threadLocal
    通过哈希算法决定落于哪一个
    Entry
    ,GC时,如果
    threadLocal
    没有引用,会被回收,即
    referent
    值为
    null
    ,否则不回收,value不会回收,因此要使用
    remove
    方法删除对应
    Entry
    ,否则可能会出现内存泄漏

set方法

ThreadLocal->set()

ThreadLocal的set方法原理是什么

第一种:如果线程第一次执行set方法,此时map为空,会创建。在此过程中初始化entry的个数为16,threshold为10,同时根据哈希值定位对应下标的entry并赋值

如果map不为空,走

ThreadLocalMap
set
方法,根据哈希值找到对应的下标。从源代码中可知:

第二种:如果该下标为空,那么直接赋值

如果该下标不为空,那么从当前下标开始遍历,直到下一个entry为null时停止

第三种:如果entry的key是当前thread,直接替换值

第四种:如果循环结束,说明遇到了空entry,那么直接赋值到该下标

如果之前发生了GC,那么entry不为空,但是key为空,此时调用

replaceStaleEntry
方法

记录此下标为

staleSlot、slotToExpunge
变量,从当前下标的前一个entry开始遍历,直到entry为null时停止,如果有回收的entry,那么记录它的下标,赋值到
slotToExpunge
变量

从当前下标的后一个entry开始遍历,直到entry为null时停止

第五种:如果遇到了key相等的情况,那么替换值,该entry与staleSlot下标的entry交换。如果向前遍历没有找到回收的entry,那么记录并赋值到

slotToExpunge
变量。清理过期entry,最后返回

第六种:如果循环结束,说明遇到了空entry,也没有找到key相等的entry。那么清除staleSlot下标的value,然后新建entry。如果有记录过期entry,那么会清理,最后返回

赋值结束后,还会进行一次尝试清理,如果没有过期entry,并且当前容量大于等于阈值,走扩容

rehash
方法

清理与扩容

expungeStaleEntry(staleSlot)
:由于传入的下标staleSlot所在entry一定是GC之后的,因此会将entry的值设为null,随后删除entry。从下一个entry开始遍历,直到entry为null时停止,如果entry是GC过的,将value置为null,否则将key重新哈希和分配,这样的目的是使得entry离正确的下标位置更接近一些。最后返回entry为null的坐标

cleanSomeSlots(i,n)
:参数n一般是当前的size值。从i的下一个entry开始遍历,每遍历一次,n的值就减少一半,直到为0时停止。如果所在下标的entry是GC过的,那么会调用一次
expungeStaleEntry(staleSlot)
方法

rehash()
:首先调用一次清理方法,然后判断当前容量是否超过阈值的四分之三(约总容量的二分之一),然后才真正扩容,每次扩容一倍。循环遍历entry数组,如果entry发生GC,那么将值设置为null,否则将key重新哈希和分配,最后重新计算阈值和当前使用容量

推荐的文章
网站地图
会员服务
关于我们
QQ:858353007
 
广告服务
加我微信
移动端访问
 
 
Copyright © 2014- 2025 www.mdaima.com All Rights Reserved.
李雷博客,专注PHP经验、PHP教程及PHP源代码开源下载分享的PHP博客!   ICP备案号:京ICP备10202169号-4