小工具类输出ThreadLocal中的值

简介: 一个输出ThreadLocal中的值小工具类,代码如下:package com.zkn.utils;import org.springframework.

一个输出ThreadLocal中的值小工具类,代码如下:

package com.zkn.utils;

import org.springframework.core.NamedThreadLocal;

import java.lang.ref.Reference;
import java.lang.reflect.Field;
import java.util.*;

/**
 * Created by zkn on 2017/10/4.
 */
public class ThreadLocalUtil {

    public static void dumpThreadDetails() {
        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;
                            System.out.println(" ref " + ref.getClass().getName() + " ref to " + ref.get());
                        } else {
                            System.out.println(value);
                        }
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
我们来测试一下:

    public static void main(String[] args) {
        ThreadLocal<Map<String, String>> threadLocal = new ThreadLocal();
        Map<String, String> maps = new HashMap<String, String>() {{
            put("zhangsan", "lisiwww");
            put("zhangsan000000", "lisi7845www");
            put("zha0124545ngsan", "lisiw02255ww");
        }};
        threadLocal.set(maps);
        ThreadLocal<List<String>> threadLocalList = new ThreadLocal();
        List<String> lists = new ArrayList<String>() {{
            add("qwwweweqqqqqq2222");
            add("qww111weweqqqqqq2222");
            add("qwww44444eweqqqqqq2222");
        }};
        threadLocalList.set(lists);
        dumpThreadDetails();
    }


在Spring中有一个ThreadLocal的扩展类:NamedThreadLocal,Spring中的很多资源都是保存在这里面,如果我们要输出NamedThreadLocal中的值的话,只需要这样改动一下就行了:

                    if (value != null) {
                        ThreadLocal threadLocal = (ThreadLocal) referEnceField.get(obj);
                        if (threadLocal instanceof NamedThreadLocal) {
                            System.out.print("spring threadlocal name: " + threadLocal + " value: ");
                        }
                        if (value instanceof Reference) {
                            Reference ref = (Reference) value;
                            System.out.println(" ref " + ref.getClass().getName() + " ref to " + ref.get());
                        } else {
                            System.out.println(value);
                        }
                    }



相关文章
|
4月前
|
存储 Java
|
存储 算法 Java
集合工具类的常用方法--小总和
集合工具类的常用方法--小总和
58 0
|
7月前
|
Java
【Java代码】反射机制处理传递给mapper文件的非Map类型参数对象(指定属性为空则设置默认值)
【Java代码】反射机制处理传递给mapper文件的非Map类型参数对象(指定属性为空则设置默认值)
60 0
|
Java
java 通过反射遍历所有字段修改值
java 通过反射遍历所有字段修改值
230 0
|
设计模式 Java
【伍】一篇让你搞懂Java中的字符串,两种实例化方式的差异以及String常用方法的使用(附示例)
【伍】一篇让你搞懂Java中的字符串,两种实例化方式的差异以及String常用方法的使用(附示例)
230 0
【伍】一篇让你搞懂Java中的字符串,两种实例化方式的差异以及String常用方法的使用(附示例)
|
Java
Java中如何循环输出对象、属性和值【亲测可用】、反射机制
Java中如何循环输出对象、属性和值【亲测可用】、反射机制
792 0
|
前端开发 Java 索引
Java 中数组 binarySearch 方法and拷贝对象工具类CopyUtils-可忽略覆盖Null值详解
[1] 该搜索键在范围内,但不是数组元素,由1开始计数,得“ - 插入点索引值”; [2] 该搜索键在范围内,且是数组元素,由0开始计数,得搜索值的索引值; [3] 该搜索键不在范围内,且小于范围(数组)内元素,返回–(fromIndex + 1); [4] 该搜索键不在范围内,且大于范围(数组)内元素,返回 –(toIndex + 1)。
144 0
Java 中数组 binarySearch 方法and拷贝对象工具类CopyUtils-可忽略覆盖Null值详解
数组常用方法总结(部分方法利用了工具类)
数组常用方法总结(部分方法利用了工具类)
109 0
|
Java 数据安全/隐私保护 索引
Java中字符串遍历、统计次数、拼接、反转案例及String常用方法
字符串遍历、统计次数、拼接、反转案例及String常用方法的简单示例
537 0
|
Java 索引
【Java】数组的常见操作以及数组作为方法参数和返回值
本期主要介绍数组的常见操作以及数组作为方法参数和返回值
249 0
【Java】数组的常见操作以及数组作为方法参数和返回值