ThreadLocal

           问题描述,在工作中一次请求 请求接口一 ,将request保存到了ThreadLocal,调用接口二,而接口二也存入了ThreadLocal,接口二完成之后将ThreadLocal
 
 romove 了,在此回到接口一时数据已经没有了,导致了问题.
 
 然后就把接口二的 ThreadLocal.remove() 这行代码干掉了......
 
 ThreadLocal 是依存于 ThreadLocalMap 的 ,key 为 Thread.currentThread();
 
    static class ThreadLocalMap {

        static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }
        
    在这里先说下对象的强弱软虚 容易记错的就是软和弱什么时候回收问题.

    1)软引用(Soft Reference):描述的是一些还有用但非必需的对象.在系统将会发生内存溢出之前,会把这些对象列入回收范围进行二次回收,也就是说系统将会发生内存溢出了,才会对他们进行回收.

    2)弱引用(Weak Reference):程度比软引用更弱一些.这些对象只能生存到下次 GC 之前.当 GC 工作时扫描到,无论内存是否足够都会将其回收.
    
    从这里我们可以发现 k 为弱引用.v为强引用.
    
    如果key被回收掉,则v可能发生内存泄露.
    
    static ThreadLocal threadLocal = new ThreadLocal();
    
    这种用法一个线程 一个线程永远只有一个KV对,并且不会被回收掉,只能是覆盖,跟随JVM启动而启动,结束而结束,可以remove删除掉自己设置的kv.
    
    另外一种用法
    class Test{
    ThreadLocal threadLocal = new ThreadLocal();
    }
    
    用对象持有 Test test = new Test();  test.threadLocal.set();
    
    如果对象使用完毕被回收(test=null; System.gc;),没有调用 threadLocal.remove();
    
    那这个 threadLocal 没有被回收,随着GC发生K被回收掉,这时候V就永远不会被回收,即使当前线程在此赋值,就会产生一条新纪录,导致内存堆积越来越多,OOM.
    
    JDK解决方案,当前线程 一定要在调用 get  set  remove  方法 会清理当前线程ThreadLocal空间内K为空的数据,赋值为NULL,帮助清理.
    
    自己解决就是一定要按规定调用remove.
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值