2015-08-30 2 views
0

Я пытаюсь отслеживать, чтобы получить идентификатор родительского потока каждого нового потока, созданного в программе с использованием AspectJ. Так как новый поток начинает выполнение с помощью метода Start(), я думал, что следующий метод должен работать:Как отслеживать идентификатор родительского потока Java с помощью aspectj?

aspect getParentThread { 
    pointcut threadStarting(): call(public void start()); 
    Object around(): threadStarting() { 
     long parentThread = Thread.currentThread().getId(); 
     Object ret = proceed(); 
     long newThread = Thread.currentThread().getId(); 
     if (parentThread != newThread) { 
       /*Store parentThread id in data structure */ 
     } 
     return ret; 
    } 
} 

Но это просто не работает. Хотя совет выполняется, даже после продолжения() завершается только один идентификатор потока. Так что я здесь не так?

ответ

1

Проблема заключается в том, что весь ваш код выполняется в родительском потоке, включая код после запуска дочернего потока, так как из родительского потока вызывается метод start().

Вы можете попробовать получить идентификатор нового потока из объекта Thread, на который вызывается метод start().

+1

Спасибо большое! Вы правы - легко получить его из объекта Thread (вместо использования текущего потока). – Arani

2

Уоррен Дью является правильным, но я хочу добавить пример кода, чтобы показать, как вы можете легко сделать это с помощью AspectJ. Вам даже не нужен совет around(), достаточно простого before().

приложение Driver:

package de.scrum_master.app; 

public class Application { 
    public static void main(String[] args) { 
     new Thread(
      new Runnable() { 
       @Override 
       public void run() {} 
      }, 
      "first thread" 
     ).start(); 
     new Thread(
      new Runnable() { 
       @Override 
       public void run() {} 
      }, 
      "second thread" 
     ).start(); 
    } 
} 

Формат:

package de.scrum_master.aspect; 

public aspect ThreadStartInterceptor { 
    before(Thread childThread) : 
     call(public void Thread+.start()) && 
     target(childThread) 
    { 
     System.out.printf(
      "%s%n Parent thread: %3d -> %s%n Child thread: %3d -> %s%n", 
      thisJoinPoint, 
      Thread.currentThread().getId(), 
      Thread.currentThread().getName(), 
      childThread.getId(), 
      childThread.getName() 
     ); 
    } 
} 
  • Как вы можете видеть, я ограничиваю метод перехвата Thread+, т.е. в Thread и подклассов экземпляров. Я делаю это явно, хотя это не является строго необходимым, потому что следующий момент уже делает это неявно:
  • Я также привязываю дочерний поток к переменной, которую можно использовать аккуратно изнутри.

журнала консоли:

call(void java.lang.Thread.start()) 
    Parent thread: 1 -> main 
    Child thread: 11 -> first thread 
call(void java.lang.Thread.start()) 
    Parent thread: 1 -> main 
    Child thread: 12 -> second thread 
Смежные вопросы