我可以获取生成当前线程的类和方法的名称吗? [英] Can I get the name of the class and method within which the current thread was spawned?

查看:90
本文介绍了我可以获取生成当前线程的类和方法的名称吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆