我正在尝试跟踪以获取使用AspectJ在程序中创建的每个新线程的父线程ID。由于新线程使用start()方法开始执行,我认为以下技术应该有效:
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;
}
}
但这根本行不通。虽然建议执行,但即使在proceed()完成后,也只有一个线程ID。那么我在这里出错了什么?
答案 0 :(得分:2)
Warren Dew 是对的,但我想添加一些示例代码,以展示如何使用AspectJ轻松完成。您甚至不需要around()
建议,简单的before()
就足够了。
驱动程序应用程序:
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
答案 1 :(得分:1)
问题是所有代码都在父线程中执行,包括子线程启动后的代码,因为start()
方法是从父线程中调用并执行的。
您可以尝试从调用Thread
方法的start()
对象获取新线程的ID。