Как найти то, что называется потоком - PullRequest
0 голосов
/ 25 сентября 2018

В отладчике Eclipse я вижу в трассировке стека много обращений к Thread.run.Шаги никогда не выходят за рамки этого.Как мне узнать, каким методом в нашем коде запущен поток?Щелчок правой кнопкой мыши не дает ничего полезного.Установка точки останова на метод run в Thread.class и проверка Target, насколько я могу судить, не говорит, кто является вызывающим.

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Если вы можете контролировать создание потоков (то есть вызываете new Thread () в своем коде или предоставляете свою собственную ThreadFactory), вы можете создать свой собственный подкласс Thread и использовать его для «инъекции» вызова-стек во время создания потока и вызова start() в переменные, которые будут в стеке.Например:

public static class KnowledgeableThread extends Thread {

    private static class KnowledgeableRunnable implements Runnable {

        StackTraceElement[] stackTraceAtInit;
        StackTraceElement[] stackTraceAtStart;

        private final Runnable actualRunnable;

        KnowledgeableRunnable(Runnable actualRunnable){
            this.actualRunnable = actualRunnable;
            this.stackTraceAtInit = Thread.currentThread().getStackTrace();
        }

        @Override
        public void run() {
            actualRunnable.run();
        }
    }

    public KnowledgeableThread(Runnable target, String name) {
        super(new KnowledgeableRunnable(target), name);
    }

    @Override
    public synchronized void start() {

        try {
            Field[] fields = Thread.class.getDeclaredFields();
            for(Field f : fields){
                if(f.getName().equals("target")){
                    f.setAccessible(true);
                    KnowledgeableRunnable knowledgeableRunnable = (KnowledgeableRunnable)f.get(this);
                    knowledgeableRunnable.stackTraceAtStart = Thread.currentThread().getStackTrace();
                }
            }

            super.start();
        } catch (IllegalAccessException e){
            throw new IllegalStateException(e);
        }
    }
}

Если вы остановитесь на точке останова "изнутри" actualRunnable.run() (например, println в приведенном ниже коде) и изучите переменные в кадре стека, принадлежащем KnowledgeableRunnable.run(), у вас должен быть доступ к двум трассам стека.

public static void a(Thread kt){
    b(kt);
}
public static void b(Thread kt){
    c(kt);
}
public static void c(Thread kt){
    kt.start();
}
public static void main(String[] args) throws InterruptedException {
    Thread kt = new KnowledgeableThread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello Foo-Bar");
        }
    }, "my-thread");
    a(kt);
    kt.join();

}
0 голосов
/ 26 сентября 2018

Установите точку останова в методе java.lang.Thread.start(), чтобы узнать, где начинается поток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...