Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
195 views
in Technique[技术] by (71.8m points)

java - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Yes, you can: I offer you 2 ways: one standard and one semi-hack.

Most of the answers go overboard while it's supposed to be built-in function in Java.

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: 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.

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(',', '
'));
            }           
        };

        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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...