如何使用 aspectj 跟踪 Java 父线程 ID?

How to track Java parent thread id using aspectj?

我正在尝试跟踪以获取在使用 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。那么我在这里弄错了什么?

问题是你所有的代码都在父线程中执行,包括子线程启动后的代码,因为start()方法是在父线程中调用并在父线程中执行的。

您可以尝试从调用 start() 方法的 Thread 对象获取新线程的 ID。

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