我可以获取生成当前线程的类和方法的名称吗?

这是一个不寻常的问题:是否有可能获得最初产生当前运行的线程的类/方法? 运行堆栈跟踪将自然停在当前线程的调用堆栈顶部。

是的,你可以:我为你提供两种方式:一种标准,一种半黑客。

大多数答案都是过分的,而它应该是Java中的内置函数。

安装安全管理器并覆盖SecurityManager.getThreadGroup() ,您可以轻松获得堆栈跟踪,也可以通过覆盖其余方法来禁用其余的安全检查。

Hacky one:在主线程中安装一个InheritableThreadLocal(名为main的那个并由方法main(String [] args)运行)。 覆盖受保护的InheritableThreadLocal.childValue(T parentValue) ,您就完成了。

注意:您将获得正在创建的线程的堆栈跟踪和父线程(引用),但这应该足以跟踪问题。

我决定编写超级简单的样本来说明它是多么容易:在这里你可以看到结果。 看一下这个样本,我想这是我在这个网站上发布过的最优雅的解决方案,主要是b / c它不明显但简单明了。

 package bestsss.util; import java.util.Arrays; public class StackInterceptor extends InheritableThreadLocal{ 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(); } } 
线程[t1,5,main]  - 创建堆栈:[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)]
线程[t2,5,main]  - 创建堆栈:[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)]

祝你好运和快乐的黑客。

通常,没有。

如果您可以控制线程创建,则可以inheritanceThread并在构造函数中注册堆栈跟踪。 当然,这是创建线程的方法,不一定是调用.start() 。 因此,更好地覆盖此方法。

但是通常你会使用线程池,你想知道哪个方法将任务提交给执行者的execute() ,而不是哪个方法启动了线程。

不,这是不可能的。 可能实现这一点的方法是before使用AspectJ对Thread.start()进行建议…当然你可以inheritanceThread ,修补JDK代码(不同的引导CLASSPATH)等,但是AspectJ似乎是最便携的优雅的解决方案。

产生对象的合作是可能的 – 它可以将信息写入Thread对象(例如,如果你想要一个hacky方式进入线程的名称,或者你可以为此目的创建一个字段),你可以在以后使用它调试等但我不认为有任何“内置”方式来获取此信息。