我有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();
}
}
}
}