亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

ThreadLocalMap里Entry為何聲明為WeakReference

標簽:
Java

Java里,每个线程都有自己的ThreadLocalMap,里边存着自己私有的对象。Map的Entry里,key为ThreadLocal对象,value即为私有对象T。在spring MVC中,常用ThreadLocal保存当前登陆用户信息,这样线程在任意地方都可以取到用户信息了


5bd6c1c700019ca807120578.jpg


跳过ThreadLocal和ThreadLocalMap的工作原理及场景不讲(看本人此专栏下另一篇文章),主要来说说Entry为什么是WeakReference

       /**
         * 此哈希表中的项继承了WeakReference
         * 它的主要引用域是key(这总是一个 ThreadLocal对象)。
         * 请注意,空key(即entry.get()== null) 表示该key不再被引用,所以该项可以从表中删除。
         * 这些被引用项的将作为下面代码中的“陈旧项”
         */
        static class Entry extends WeakReference<ThreadLocal<?>> {            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {                super(k);
                value = v;
            }
        }

先来看看WeakReference的作用,百度一下:

WeakReference是Java语言规范中为了区别直接的对象引用(程序中通过构造函数声明出来的对象引用)而定义的另外一种引用关系。
WeakReference标志性的特点是:reference实例不会影响到被应用对象的GC回收行为(即只要对象被除WeakReference对象之外所有的对象解除引用后,该对象便可以被GC回收),只不过在被对象回收之后,reference实例想获得被应用的对象时程序会返回null

我的理解就是,WeakReference对应用的对象users是弱引用,不会影响到users的GC行为。
如果是强引用的话,在线程运行过程中,我们不再使用users了,将users置为null,但users在线程的ThreadLocalMap里还有引用,导致其无法被GC回收(当然,可以等到线程运行结束后,整个Map都会被回收,但很多线程要运行很久,如果等到线程结束,便会一直占着内存空间)。
而Entry声明为WeakReference,users置为null后,线程的threadLocalMap就不算强引用了,users就可以被GC回收了。map的后续操作中,也会逐渐把对应的"stale entry"清理出去,避免内存泄漏

所以,我们在使用完ThreadLocal变量时,尽量用threadLocal.remove()来清除,避免threadLocal=null的操作。
前者remove()会同时清除掉线程threadLocalMap里的entry,算是彻底清除
而后者虽然释放掉了threadLocal,但线种threadLocalMap里还有其"stale entry",后续还需要处理



作者:芥末无疆sss
链接:https://www.jianshu.com/p/6e80ba556caf
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。


點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
Web前端工程師
手記
粉絲
49
獲贊與收藏
218

關注作者,訂閱最新文章

閱讀免費教程

  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消