来自所有线程的Java ThreadLocal转储值

时间:2019-06-01 05:18:12

标签: java multithreading reflection thread-local thread-local-storage

我有ThreadLocal个存储MyClass的实例。我希望从所有线程中转储(打印,sysout)MyClass的值(实例)。

我有两个实现,但是它们都仅从当前线程(Thread.currentThread())中输出值。 有什么想法我错过了吗?

P.S。不幸的是,ThreadLocal API是私有的,因此我必须使用反射来访问实际上保留值的ThreadLocalMap(例如,参见Thread.threadLocals等)

public class ThreadLocalT{
    private Method getMap;
    private Field tableField;
    private Field value;
    private Method getEntry;

    public ThreadLocalT() {
        try {
            getMap = ThreadLocal.class.getDeclaredMethod("getMap", Thread.class);
            getMap.setAccessible(true);

            Class<?> threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
            getEntry = threadLocalMapClass.getDeclaredMethod("getEntry", ThreadLocal.class);
            getEntry.setAccessible(true);
            tableField = threadLocalMapClass.getDeclaredField("table");
            tableField.setAccessible(true);

            Class<?> entryClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap$Entry");
            value = entryClass.getDeclaredField("value");
            value.setAccessible(true);            
        } catch (NoSuchMethodException | SecurityException | ClassNotFoundException | NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void dump(ThreadLocal<MyClass> pThreadLocal) {
        // Implementation I
        for (Thread item : Thread.getAllStackTraces().keySet()) {
            try {
                Object data = getMap.invoke(pThreadLocal, item);
                if (data != null) {
                    Object entry = getEntry.invoke(data, pThreadLocal);
                    if (entry != null) {

                        Object obj = value.get(entry);
                        if (obj != null) {
                            System.out.println(item);
                            System.out.println("data = " + data);
                            System.out.println("entry = " + entry);
                            System.out.println("obj = " + obj);
                        }
                    }
                }
            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        // Implementation II
        for (Thread item : Thread.getAllStackTraces().keySet()) {
            try {
                Object result = getMap.invoke(pThreadLocal, item);
                if (result != null) {
                    Object table = tableField.get(result);
                    if (table != null) {
                        int threadLocalCount = Array.getLength(table);
                        for (int i=0; i < threadLocalCount; i++) {
                            Object entry = Array.get(table, i);
                            if (entry != null) {
                                Object obj = value.get(entry);
                                if (obj instanceof MyClass) {
                                    System.out.println("obj = " + obj);
                                }
                            }
                        }
                    }
                }
            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

0 个答案:

没有答案