我可以获取生成当前线程的类和方法的名称吗? [英] Can I get the name of the class and method within which the current thread was spawned?
问题描述
这是一个不寻常的问题:是否有可能获得最初产生当前正在运行的线程的类/方法?运行堆栈跟踪将自然停在当前线程的调用堆栈顶部。
Here's an unusual one: is it possible to obtain the class/method that originally spawned the currently running thread? Running a stack trace will naturally stop at the top of the call stack for the current thread.
推荐答案
是的,您可以:
我为您提供了两种方式:一种是标准方式,一种是半方式。
Yes, you can: I offer you 2 ways: one standard and one semi-hack.
大多数答案都过分,而它应该是Java中的内置函数。
Most of the answers go overboard while it's supposed to be built-in function in Java.
安装安全管理器并覆盖 SecurityManager.getThreadGroup()
,您可以轻松获得堆栈跟踪,可选可以通过覆盖其余的方法来禁用其余的安全检查。
Install a security manager and override SecurityManager.getThreadGroup()
, you can get the stack trace easily, optionally you can disable the rest of the secutiry checks by overriding the rest of the methods too.
Hacky one:在主线程中安装一个InheritableThreadLocal(名为main的一个并运行方法main(String [] args))。覆盖受保护的 InheritableThreadLocal.childValue(T parentValue)
,您就完成了。
Hacky one: install an InheritableThreadLocal in the main thread (the one named main and run by method main(String[] args)). Override the protected InheritableThreadLocal.childValue(T parentValue)
and you are done.
注意:您获得的堆栈跟踪正在创建的线程和父线程(引用),但这应该足以跟踪问题。
Note: you get the stacktrace of the thread being created and the parent thread (reference) but that should be enough to trace issues.
我决定编写超级简单的示例来说明它是多么容易:
在这里你可以看到结果。看一下这个样本,我想这是我在这个网站上发布过的最优雅的解决方案,主要是b / c它不明显但简单明了。
I decided to write the super simple sample to illustrate how easy it is: Here you can see the results. Looking at the sample, I guess that the most elegant solution I have ever posted on this site, mostly b/c it's non-obvious but simple and smart.
package bestsss.util;
import java.util.Arrays;
public class StackInterceptor extends InheritableThreadLocal<StackTraceElement[]>{
public static final StackInterceptor instance;
static{
instance = new StackInterceptor();
instance.set(new Throwable().getStackTrace());
}
@Override
protected StackTraceElement[] childValue(StackTraceElement[] parentValue) {
return new Throwable().getStackTrace();
}
//test//
public static void main(String[] args) {
Runnable r= new Runnable(){
@Override
public void run() {
System.out.printf("%s - creation stack: %s%n", Thread.currentThread(), Arrays.toString(instance.get()).replace(',', '\n'));
}
};
Thread t1 = new Thread(r, "t1");
//spacer
Thread t2 = new Thread(r, "t2");
t1.start();
t2.start();
}
}
Thread[t1,5,main] - creation stack: [bestsss.util.StackInterceptor.childValue(StackInterceptor.java:13)
bestsss.util.StackInterceptor.childValue(StackInterceptor.java:1)
java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:334)
java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:242)
java.lang.ThreadLocal.createInheritedMap(ThreadLocal.java:217)
java.lang.Thread.init(Thread.java:362)
java.lang.Thread.(Thread.java:488)
bestsss.util.StackInterceptor.main(StackInterceptor.java:25)]
Thread[t2,5,main] - creation stack: [bestsss.util.StackInterceptor.childValue(StackInterceptor.java:13)
bestsss.util.StackInterceptor.childValue(StackInterceptor.java:1)
java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:334)
java.lang.ThreadLocal$ThreadLocalMap.(ThreadLocal.java:242)
java.lang.ThreadLocal.createInheritedMap(ThreadLocal.java:217)
java.lang.Thread.init(Thread.java:362)
java.lang.Thread.(Thread.java:488)
bestsss.util.StackInterceptor.main(StackInterceptor.java:27)]
祝你好运和快乐的黑客攻击。
Good luck and happy hacking.
这篇关于我可以获取生成当前线程的类和方法的名称吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!