zoukankan      html  css  js  c++  java
  • 一个工作中碰到的小坑

    记录一个小坑,开发压测平台的时候碰到的。

    背景:现在在开发压测平台,抽象类一些常用拦截器作为 starter ,供所有 module 使用(目前我们有7个) 。starter 中使用的一些 entity, 使用了 Threadlocal ,用于保存用户信息和部门信息

    问题:在 module 依赖了 starter 后,读不到保存在 Threadlocal 里的用户信息,如 roleID,businessName。

    过程: 拦截器和业务代码里都加了以下打印 ThreadlocalMap 的代码来看看原因。

              最后 double check 了一下,因为定义保存在 Threadlocal 里的 entity 类,存在不同的报名,被编译器认为是两个不同的类,所以是取不到的,破案。

              其实最终发现原因和这段代码没有关系,只是在仔细检查了打印内容的时候发现了不一样的地方,so。不过学习到了很多 Threadlocal 的知识,学习一下。

              记录下来,作为警示。

    以下是代码:

    /**
    * 我是打印ThreadLocalMap的分割线
    *
    */

    try {
    //获取当前线程对象
    Thread thread = Thread.currentThread();
    //获取Thread中的threadLocals对象
    Field threadLocals = Thread.class.getDeclaredField("threadLocals");
    threadLocals.setAccessible(true);
    //ThreadLocalMap是ThreadLocal中的一个内部类,并且访问权限是default
    // 这里获取的是ThreadLocal.ThreadLocalMap
    Object threadLocalMap = threadLocals.get(thread);

    //这里要这样获取ThreadLocal.ThreadLocalMap
    Class threadLocalMapClazz = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
    //获取ThreadLocalMap中的Entry对象
    Field tableField = threadLocalMapClazz.getDeclaredField("table");
    tableField.setAccessible(true);
    //获取ThreadLocalMap中的Entry
    Object[] objects = (Object[]) tableField.get(threadLocalMap);

    //获取ThreadLocalMap中的Entry
    Class entryClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap$Entry");
    //获取ThreadLocalMap中的Entry中的value字段
    Field entryValueField = entryClass.getDeclaredField("value");
    entryValueField.setAccessible(true);
    //Entry继承了WeakReference,WeakReference继承了Reference
    Field referEnceField = Reference.class.getDeclaredField("referent");
    referEnceField.setAccessible(true);

    Arrays.stream(objects).filter(obj -> obj != null).forEach((obj) -> {
    try {
    Object value = entryValueField.get(obj);
    if (value != null) {
    if (value instanceof Reference) {
    Reference ref = (Reference) value;
    log.info(ref.getClass().getName() + "------>" + ref.get());
    } else {
    log.info("------>" + value.getClass());
    }
    }
    } catch (IllegalAccessException e) {
    e.printStackTrace();
    }
    });
    } catch (Exception e) {
    e.printStackTrace();
    }


    /**
    * 我是打印ThreadLocalMap的结束
    */
  • 相关阅读:
    Android使用LocalSocket抓取数据
    求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}
    链表A和B的有序合并,合并过程不产生新的节点,合并后B消失
    Android中intent如何传递自定义数据类型
    字符串的排列组合问题
    android.net.LocalSocket
    [转]OWC生成柱图,线图,饼图
    利用C#对远程服务进行操作
    域备份&域还原
    ActiveReports for .NET 简单使用
  • 原文地址:https://www.cnblogs.com/spillage/p/14950987.html
Copyright © 2011-2022 走看看