【问题标题】:How to track Java parent thread id using aspectj?如何使用 aspectj 跟踪 Java 父线程 ID?
【发布时间】:2015-09-05 19:17:46
【问题描述】:

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

【问题讨论】:

    标签: java multithreading aspectj aop


    【解决方案1】:

    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
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 非常感谢!你是对的——很容易从 Thread 对象中获取它(而不是使用当前线程)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-10
      • 2021-12-31
      • 1970-01-01
      相关资源
      最近更新 更多