纠纷奇闻社交美文家庭
投稿投诉
家庭城市
爱好生活
创业男女
能力餐饮
美文职业
心理周易
母婴奇趣
两性技能
社交传统
新闻范文
工作个人
思考社会
作文职场
家居中考
兴趣安全
解密魅力
奇闻笑话
写作笔记
阅读企业
饮食时事
纠纷案例
初中历史
说说童话
乐趣治疗

ThreadLocal核心源码解析

2月22日 亡命徒投稿
  1前言
  此类提供线程本地变量。这些变量与普通变量不同,因为每个访问一个变量(通过其get或set方法)的线程都有其自己的,独立初始化的变量副本。ThreadLocal实例通常是期望将状态与线程(例如,用户ID或事务ID)关联的类中的privatestatic字段。
  例如,下面的类生成每个线程本地的唯一标识符。线程的ID是在第一次调用ThreadId。get()时赋值的,并且在以后的调用中保持不变。
  只要线程是活跃的并且ThreadLocal实例是可访问的,则每个线程都对其线程本地变量的副本持有隐式的引用。线程消失后,线程本地实例的所有副本都会被GC(除非存在对这些副本的其他引用)。
  2继续体系继承?不存在的,这其实也是java。lang包下的工具类图片标题但是ThreadLocal定义带有泛型,说明可以储存任意格式的数据。图片标题3属性ThreadLocal依赖于附加到每个线程(Thread。threadLocals和InheritableThreadLocals)的线程线性探测哈希表。ThreadLocal对象充当键,通过threadLocalHashCode进行搜索。这是一个自定义哈希码(仅在ThreadLocalMaps中有用),它消除了在相同线程使用连续构造的threadlocal的常见情况下的冲突,而在不太常见的情况下仍然表现良好。一句话总结:ThreadLocal通过这样的hashCode,计算当前ThreadLocal在ThreadLocalMap中的索引图片标题图片标题连续生成的哈希码之间的差值,关于该值的设定,可参考文章ThreadLocal的hash算法(关于0x61c88647)图片标题注意static修饰,ThreadLocalMap会被set多个ThreadLocal,而多个ThreadLocal就根据threadLocalHashCode区分图片标题4ThreadLocalMap
  ThreadLocalMap是自定义的哈希表,仅适用于维护线程本地的值。没有操作导出到ThreadLocal类之外。该类是包私有的,允许在Thread类中的字段声明。为了帮助处理非常长的使用寿命,哈希表节点使用WeakReferences作为键。但是,由于不使用引用队列,因此仅在表空间不足时,才保证删除过时的节点。staticclassThreadLocalMap{此哈希表中的节点使用其主引用字段作为键(始终是一个ThreadLocal对象)继承了WeakReference。请注意,空键(即entry。get()null)意味着不再引用该键,因此可以从表中删除该节点。在下面的代码中,此类节点称为staleentriesstaticclassEntryextendsWeakReferenceThreadL?{与此ThreadLocal关联的值OEntry(ThreadL?k,Objectv){super(k);}}初始容量必须是2的幂privatestaticfinalintINITIALCAPACITY16;table数组,必要时扩容table。length必须是2的幂privateEntry〔〕table中的节点个数privateintsize0;下一次扩容的阈值默认为0特点key是ThreadLocal的引用value是ThreadLocal保存的值数组的数据结构5set5。1ThreadLocalset
  将此线程本地变量的当前线程副本设置为指定值。大多数子类将不需要重写此方法,而仅依靠initialValue方法来设置线程本地变量的值。
  执行流程获取当前线程获取线程所对应的ThreadLocalMap,从这可以看出每个线程都是独立的,所以此方法天然线程安全判断map是否为null否,则K。V对赋值,k为this,即当前的ThreaLocal对象是,则初始化一个ThreadLocalMap来维护K。V对
  来具体看看ThreadLocalMap中的set5。2ThreadLocalMapsetprivatevoidset(ThreadL?key,Objectvalue){新引用指向tableEntry〔〕intlentab。获取对应ThreadLocal在table中的索引,注意这里是hashCode与2幂次长度1(想起来为什么这样计算更好了吗?)intikey。threadLocalHashCode(len1);从该下标开始循环遍历1、如遇相同key,则直接替换value2、如果该key已经被回收失效,则替换该失效的keyfor(Entryetab〔i〕;e!etab〔inextIndex(i,len)〕){ThreadL?ke。get();找到内存地址一样的ThreadLocal,直接替换if(kkey){e。}若k为null,说明ThreadLocal被清理了,则替换当前失效的kif(knull){replaceStaleEntry(key,value,i);}}找到空位,创建节点并插入tab〔i〕newEntry(key,value);table内元素size自增达到阈值(数组大小的三分之二)时,执行扩容if(!cleanSomeSlots(i,sz)szthreshold)rehash();}
  注意通过hashCode计算的索引位置i处如果已经有值了,会从i开始,通过1不断的往后寻找,直到找到索引位置为空的地方,把当前ThreadLocal作为key放进去。6getpublicTget(){获取当前线程ThreadtThread。currentThread();获取当前线程对应的ThreadLocalMapThreadLocalMapmapgetMap(t);如果map不为空if(map!null){取得当前ThreadLocal对象对应的EntryThreadLocalMap。Entryemap。getEntry(this);如果不为空,读取当前ThreadLocal中保存的值if(e!null){SuppressWarnings(unchecked)Tresult(T)e。}}否则都执行setInitialValuereturnsetInitialValue();}
  privateTsetInitialValue(){获取初始值,一般是子类重写TvalueinitialValue();获取当前线程ThreadtThread。currentThread();获取当前线程对应的ThreadLocalMapThreadLocalMapmapgetMap(t);如果map不为nullif(map!null)调用ThreadLocalMap的set方法进行赋值map。set(this,value);否则创建个ThreadLocalMap进行赋值elsecreateMap(t,value);}
  接着我们来看下ThreadLocalMapgetEntry得到当前thradLocal对应的值,值的类型是由thradLocal的泛型决定的由于thradLocalMapset时解决数组索引位置冲突的逻辑,导致thradLocalMapget时的逻辑也是对应的首先尝试根据hashcode取模数组大小1索引位置i寻找,找不到的话,自旋把i1,直到找到索引位置不为空为止privateEntrygetEntry(ThreadL?key){计算索引位置:ThreadLocal的hashCode取模数组大小1intikey。threadLocalHashCode(table。length1);Entryetable〔i〕;e不为空,并且e的ThreadLocal的内存地址和key相同,直接返回,否则就是没有找到,继续通过getEntryAfterMiss方法找if(e!nulle。get()key)else这个取数据的逻辑,是因为set时数组索引位置冲突造成的returngetEntryAfterMiss(key,i,e);}自旋i1,直到找到为止privateEntrygetEntryAfterMiss(ThreadL?key,inti,Entrye){Entry〔〕intlentab。在大量使用不同key的ThreadLocal时,其实还蛮耗性能的while(e!null){ThreadL?ke。get();内存地址一样,表示找到了if(kkey)删除没用的keyif(knull)expungeStaleEntry(i);继续使索引位置1elseinextIndex(i,len);etab〔i〕;}}6扩容
  ThreadLocalMap中的ThreadLocal的个数超过阈值时,ThreadLocalMap就要开始扩容了,我们一起来看下扩容的逻辑:privatevoidresize(){拿出旧的数组Entry〔〕oldTintoldLenoldTab。新数组的大小为老数组的两倍intnewLenoldLen2;初始化新数组Entry〔〕newTabnewEntry〔newLen〕;intcount0;老数组的值拷贝到新数组上for(intj0;joldLj){EntryeoldTab〔j〕;if(e!null){ThreadL?ke。get();if(knull){e。HelptheGC}else{计算ThreadLocal在新数组中的位置inthk。threadLocalHashCode(newLen1);如果索引h的位置值不为空,往后1,直到找到值为空的索引位置while(newTab〔h〕!null)hnextIndex(h,newLen);给新数组赋值newTab〔h〕e;}}}给新数组初始化下次扩容阈值,为数组长度的三分之二setThreshold(newLen);tablenewT}
  源码注解也比较清晰,我们注意两点:
  扩容后数组大小是原来数组的两倍;扩容时是绝对没有线程安全问题的,因为ThreadLocalMap是线程的一个属性,一个线程同一时刻只能对ThreadLocalMap进行操作,因为同一个线程执行业务逻辑必然是串行的,那么操作ThreadLocalMap必然也是串行的。7总结
  ThreadLocal是非常重要的API,我们在写一个中间件的时候经常会用到,比如说流程引擎中上下文的传递,调用链ID的传递等等,非常好用,但坑也很多。
  作者:JavaEdge在掘金
  链接:https:juejin。impost5eb423ef6fb9a0435f093e5e
投诉 评论 转载

营销的信任4种可实操性方法作者:小蚱蜢简介:8年互联网营销实战经验,乐于为大家分享实战经验。寻找互联网营销同行交流经验提升自我品牌故事品牌的历程证明了实现了在消费者中的信任。广义的品牌是具有……2021年广西三个百万千瓦级新能源项目实现开工助力全区能源结来源:自治区发展和改革委新能源处作者:黄华烨2021年12月11日,全国发展和改革工作会议在京召开,大型风电光伏基地再次作为重点发展任务被提及。相较于分布式新能源建设,基……InfobirdCo。,Ltd宣布发布年报20F提供创新客户交互解决方案的中国AISaaS(软件即服务)服务商InfobirdCo。,Ltd(Nasdaq:IFBD)(以下简称讯鸟,公司),今日宣布已向美国证券交易委员会(S……广饶县重点项目观摩团莅临山东卓文信息科技有限公司调研指导2020年12月4日下午,广饶县委书记梁润生、县长陈伟颂、县委副书记张子柱、县人大主任李道明、县政协主席孙翠秀率全县重点项目观摩团在宇通集团副总经理杨向波、卓文科技总经理徐通通……湖南醴陵富豪放弃铁饭碗创业,逆袭人生大赚百亿财富湖南知名富豪:放弃铁饭碗创业,逆袭人生大赚百亿财富推荐语:一部近代史,有半部是湖南人写就。说到中国近代史,人们经常会发出这样的感慨。近代湖南人才辈出,每一次历史潮头,总有……生而出色比亚迪海豚,专为新世代年轻用户打造的纯电新物种生而出色的比亚迪海豚是专为新世代年轻用户打造的纯电新物种,作为海洋车系的首款车型,海豚同时还是首款采用海洋美学设计理念的车型,首款使用比亚迪新LOGO的车型,首款基于比亚迪e平……EasyC43,头文件的编写大家好,我是梁唐。这是EasyC系列的第43篇,来聊聊头文件的编写。想要追求更好阅读体验的同学,可以访问github仓库:EasyLeetCode。编写头文件……碳中和科华数据公司与国网综合能源服务集团有限公司签订《战略合作协议》,,围绕光伏逆变器、储能变流器及系统集成、新能源项目合作开发、已建新能源电站处置、综合能源服务业务、数据中心、智慧电能等领……璀璨的星qdc天王星圈铁耳机评测自从qdc推出圈铁耳机以来,这个国产定制耳机品牌便受到众多烧友的高度关注。一来产品线得以扩展,二来qdc将高端定制与圈铁耳塞相结合,带来圈铁耳塞更完善的私模定制解决方案。在首款……ThreadLocal核心源码解析1前言此类提供线程本地变量。这些变量与普通变量不同,因为每个访问一个变量(通过其get或set方法)的线程都有其自己的,独立初始化的变量副本。ThreadLocal实例通……LG将为通用BoltEV召回承担9。18亿美元成本等7条快讯1、LG将为通用BoltEV召回承担9。18亿美元成本10月12日,韩国LG化学和LG电子表示,两家公司最新一季度的业绩将计入与通用汽车召回BoltEV相关的约1。1万亿……0风险创业宣传词违反广告法,魔贴世家现行四级代理模式有何特色在上篇报道中,我们了解到了魔贴世家旗下的化妆品涉及到的相关宣传是否存在问题,在本篇报道中,我们将重点关注的是魔贴世家所推行的奖金制度。四级代理?三重奖励关于魔贴世家……
AI风口科大讯飞市值千亿,收获人工智能红利日语与汉字有哪些渊源?50音起源带你了解网络付费刷课灰色产业链须从根上治三星在美申请QNED商标被拒是通用词不能注册为什么国产手机只有华为做到3D结构光,抬起唤醒功能?特斯拉事故频发,竟是因为车主缺乏教育?投资路上,普通人该如何正确看待各类观点电脑主机嗡嗡响,会影响电脑吗?教师专业发展与教师专业化的论文高职足球课战术意识现状与培养策略论文公路文化建设思考论文有形动产租赁税制论文
华硕X54HR系列如何使用隐藏分区恢复Windows7系统如何对号入座为你的伴侣选择合适的情人节避孕套餐呢阿尔法视角深圳赛格大厦振动事件,智慧楼宇路还有多长?Win10装win7系统开机出现蓝屏与别人家的孩子生活三十天之第六天用酵母文库单杂交发现枸橘转录因子调控干旱胁迫淀粉酶代谢的机制 美股暴跌对中国市场有何影响热传聚热点网 描写夏天好段2020最新高铁儿童票标准男士毛衣搭配什么裤子好看描写夏天的诗句赏析大全被迫退役!魔兽无人问津,巅峰单换詹皇,18年职业生涯赚了多少

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找美丽时装彩妆资讯历史明星乐活安卓数码常识驾车健康苹果问答网络发型电视车载室内电影游戏科学音乐整形