下面是一个不常见的问题:是否有可能获得最初产生当前正在运行的线程的类/方法?运行堆栈跟踪自然会停止在当前线程调用堆栈的顶部。我可以获取当前线程产生的类和方法的名称吗?
回答
是的,你可以: 我给你2种方法:一个标准和一个半劈。
大部分答案都是过度的,而它应该是Java中的内置函数。
安装安全管理器并覆盖SecurityManager.getThreadGroup()
,您可以轻松获取堆栈跟踪,也可以通过重写其余方法来禁用其他的安全检查。
哈克之一:在主线程安装的InheritableThreadLocal(所述一个命名主要和方法主要(字串[] args)运行)。覆盖受保护的InheritableThreadLocal.childValue(T parentValue)
,就完成了。
注意:你所创建的线程和父线程(参考)的堆栈跟踪,但应该是足够的追查问题。
我决定写超级简单的示例来说明它是多么容易: 在这里你可以看到的结果。看看这个示例,我猜想我曾经在这个网站上发布的最优雅的解决方案,大多数是B/C,但它并不明显,但简单而智能。
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)]
好运和快乐的黑客攻击。
InheritableThreadLocal的解决方案是一个美丽的解决方案。我想知道如果main()的源不可用,是否可以使用它(例如,在应用程序服务器的情况下) – 2011-09-21 07:00:50
当然,main()是第一个(通常几乎是erm)方法在应用程序中调用。如果它不可用,在初始化threadLocal后,所有的child(和grand-child ++)线程都会被追踪。总之尽快完成init部分。 – bestsss 2011-09-21 08:05:01
通常,没有。
如果你能控制你的线程的创建,你可以继承线程并注册在构造函数中的堆栈跟踪。当然,这是创建线程的方法,不一定是调用.start()
的那个方法。因此更好的重写这个方法。
但是,您经常会使用线程池,而您想知道哪个方法将任务提交给执行程序的,而不是哪个方法启动线程。
如果你控制池,没有什么值得怀疑的,你甚至可以控制threadFactory,所以它是线程工厂。 – bestsss 2011-06-16 06:52:47
@bestsss:是的。我的观点是,这种线程工厂方法通常不会是你真正想知道的** - 你会想知道谁(哪个方法)将工作提交给了线程池(或谁创建了可运行对象)。为此,您的线程池将不得不向所有任务添加元数据,并以某种方式提供一种方法来检索此操作。 – 2011-06-16 12:18:49
ŭlo,'AbstractExecutorService'中有'newTaskFor(...)'来装饰任务。相反,知道第一个任务产生线程的时间可能非常重要。虽然不是很明显,但为什么新创建的线程从父类继承了很多,并且需要一个勤奋的ThreadFactory来防止泄漏(ClassLoader,AccessControlContext,ThreadGroup等) – bestsss 2011-06-16 12:23:33
不,这是不可能的。可能是实现这一目标的方法是在Thread.start()
有before
建议使用AspectJ ...当然,你也可以继承Thread
,补丁JDK代码(不同的启动CLASSPATH)等,但AspectJ的似乎是最便携和优雅的解决方案。
doh,这么多工作:) – bestsss 2011-06-16 06:47:50
- 1. 获取当前正在执行的当前线程的方法名称
- 2. 获取当前方法的名称
- 3. 可以在java产品中记录源类名称和方法名称吗?
- 4. 我可以通过表名获取模型类的名称吗?
- 5. 如何在静态方法中获取当前类的名称?
- 6. 获取当前类的名称
- 7. 我可以通过名称调用类的静态方法吗?
- 8. 我可以使用内建名称作为Python类的方法名称吗?
- 9. BCEL - 获取类名称,元素名称和方法名称
- 10. 获取当前正在执行的方法的名称
- 11. RTTI:我可以通过名称获取类型吗?
- 12. 我可以找出我使用的方法的名称吗?
- 13. JavaScript:是否可以获取当前名称空间的内容?
- 14. 获取当前MembershipProvider名称
- 15. 如何在squeak中获取当前方法的名称?
- 16. 如何在Delphi 7中获取当前方法的名称?
- 17. 在C++中获取当前方法的名称
- 18. 获取当前执行方法的名称
- 19. android获取多态方法的当前活动名称
- 20. 我可以从实体的类方法中获取EntityManager吗?
- 21. 我可以在pthreads/Linux中设置线程的名称吗?
- 22. cURL + PHP获取类名称,可能吗?
- 23. 我可以锁定当前线程的SQLite表吗?
- 24. 获取以无效方法生成的随机数的名称
- 25. 我可以使用当前路由名称建立链接吗?
- 26. 获取在特定线程中执行的方法的名称
- 27. 我可以使用Java反射获取方法字段名称吗?
- 28. 如何在运行时使用反射从当前线程获取当前方法名称?
- 29. 我可以从PHP获取文件的简短DOS名称吗?
- 30. 获取当前VBA函数的名称
我希望你这样做是因为一些冒险的调试,而不是什么重要的。 – 2011-06-15 21:52:45
哈哈,你假设正确。自从我走上这条路后,我一直没有停下我的鼻子:-D – Wilco 2011-06-15 21:59:46
相关(但不完全相同):[在Java中伪造栈跟踪](http://stackoverflow.com/questions/6270256/forging-a- stack-trace-in-java) – 2011-06-15 22:02:56