小工具类输出ThreadLocal中的值

来源:互联网 发布:电动牙刷 知乎 推荐 编辑:程序博客网 时间:2024/06/06 12:33

一个输出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);                        }                    }



原创粉丝点击