zoukankan      html  css  js  c++  java
  • ThreadLocal

    ThreadLocal  本地线程副本工具类

    用法:

      本地线程副本工具类,顾名思义:线程内的变量,只在线程内部有效。

    结构图:

      

    我的理解:

      所有的数据,保存在Thread当中。以ThreadLocal为key,需要保存的内容为值,保存在Thread的threadLocals变量当中。

      保存的步骤:

        源码如下:

          

        1、首先获取当前线程,得到ThreadLocalMap。

        2、ThreadLocal内部保存的数据结构为:key 为ThreadLocal的对象,value为需要保存的内容。

      取数据的步骤:

        源码如下:

          

        1、依然是先获取当前线程,再获取Map。

        2、再根据ThreadLocal的对象值为key,获取Map内对应的值value。

    由源码与结构图可以清楚的了解ThreadLocal的存储实现。 

     工作当中的应用举例:

      定位问题需要log,而log中,最重要的因素不乏以下这些:线程名,用户名,方法名,异常堆栈……等。其中如果我们需要log打印用户名,那么如何传入用户名呢?此时ThreadLocal就派上用场了。

      1、在权限校验的时候,将用户名,通过本地线程工具类ThreadLocal存入。

      2、需要在线程中使用的时候,再取出来即可。

    可能造成的问题:OOM

      1、如果线程存在复用问题,则需要在使用完成后,清空对应的值。

      2、弱引用问题。    

        关于ThreadLocalMap<ThreadLocalObject>弱引用问题:

        当线程没有结束,但是ThreadLocal已经被回收,则可能导致线程中存在ThreadLocalMap<nullObject>的键值对,造成内存泄露。(ThreadLocal被回收,ThreadLocal关联的线程共享变量还存  在)。虽然ThreadLocal的get,set方法可以清除ThreadLocalMap中key为null的value,但是get,set方法在内存泄露后并不会必然调用,所以为了防止此类情况的出现,我们有两种手段。

        2.1、使用完线程共享变量后,显示调用ThreadLocalMap.remove方法清除线程共享变量;

        2.2、JDK建议ThreadLocal定义为private static,这样ThreadLocal的弱引用问题则不存在了。

  • 相关阅读:
    MySQL运维案例分析:Binlog中的时间戳
    身边有位“别人家的程序员”是什么样的体验?
    苹果收取30%过路费_你是顶是踩?
    1019 数字黑洞 (20 分)C语言
    1015 德才论 (25 分)C语言
    1017 A除以B (20 分)C语言
    1014 福尔摩斯的约会 (20 分)
    求n以内最大的k个素数以及它们的和、数组元素循环右移问题、求最大值及其下标、将数组中的数逆序存放、矩阵运算
    1005 继续(3n+1)猜想 (25 分)
    爬动的蠕虫、二进制的前导的零、求组合数、Have Fun with Numbers、近似求PI
  • 原文地址:https://www.cnblogs.com/chen--biao/p/9947707.html
Copyright © 2011-2022 走看看