博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程-----源码解析ThreadLocalMap里Entry为何声明为WeakReference?
阅读量:6674 次
发布时间:2019-06-25

本文共 2056 字,大约阅读时间需要 6 分钟。

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

public class UserContext {    private static final ThreadLocal
userInfoLocal = new ThreadLocal
(); public static UserInfo getUserInfo() { return userInfoLocal.get(); } public static void setUserInfo(UserInfo userInfo) { userInfoLocal.set(userInfo); } public static void clear() { userInfoLocal.remove(); }}

 

这里,跳过ThreadLocal和ThreadLocalMap的工作原理及场景不讲,主要来说说Entry为什么是WeakReference?

/** * The entries in this hash map extend WeakReference, using * its main ref field as the key (which is always a * ThreadLocal object).  Note that null keys (i.e. entry.get() * == null) mean that the key is no longer referenced, so the * entry can be expunged from table.  Such entries are referred to * as "stale entries" in the code that follows. */static class Entry extends WeakReference
> { /** 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对应用的对象userInfoLocal是弱引用,不会影响到userInfoLocal的GC行为。如果是强引用的话,在线程运行过程中,我们不再使用userInfoLocal了,将userInfoLocal置为null,但userInfoLocal在线程的ThreadLocalMap里还有引用,导致其无法被GC回收(当然,可以等到线程运行结束后,整个Map都会被回收,但很多线程要运行很久,如果等到线程结束,便会一直占着内存空间)。而Entry声明为WeakReference,userInfoLocal置为null后,线程的threadLocalMap就不算强引用了,userInfoLocal就可以被GC回收了。map的后续操作中,也会逐渐把对应的"stale entry"清理出去,避免内存泄漏。

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

 转载-----

作者:
    
出处:

转载于:https://www.cnblogs.com/technologykai/articles/9071617.html

你可能感兴趣的文章
Nagios简介与安装(1)
查看>>
centos 本地yum配置
查看>>
使用Vundle来管理vim的插件
查看>>
我们容易忽略的WebDriver 的一些方法
查看>>
Windows借助脚本实现自动化加域
查看>>
构造函数私有化
查看>>
我的友情链接
查看>>
Linux Shell编程
查看>>
归档与反归档
查看>>
Learning Data Structure_5_图(2)
查看>>
HDS G1000和Gx00的端口属性
查看>>
Innodb中mysql如何快速删除2T的大表
查看>>
bash基本命令的使用(笔记)
查看>>
windows_learn 002 用户管理和组策略
查看>>
kafka性能优化
查看>>
含有echart 图表的报表打印
查看>>
域控迁移为08 R2后无法访问Linux服务器共享
查看>>
我的友情链接
查看>>
华为认证考试
查看>>
我的友情链接
查看>>