java - 如何在 Java 中使用 AspectJ 记录父级和子级的线程 ID

标签 java multithreading aop aspectj

我是 AspectJ 的新手。能够创建一个简单的 JUnit 和 Aspect 类来记录 ThreadId,从而记录父线程 Id。但我不知道如何记录 Child ThreadId。

鉴于以下代码片段,我想使用 AspectJ 记录父级和子级的线程 ID。

JUnit:

@Test
public void testExecutorService() {
    ExecutorService service = Executors.newSingleThreadExecutor();
    Runnable task = new Runnable() {
        @Override
        public void run() {
            System.out.println("working on the task");
        }
    };
    service.submit(task);
}

方面:以下方面记录父线程Id。

before() :
    call(* ExecutorService+.submit(..))
 {
    System.out.println("Parent Thread Id: "+Thread.currentThread().getId());
    //System.out.println("Child Thread Id: "+??); //?? - how to capture child thread id?
 }

我知道它在这里使用“之前”建议,并且它正在拦截提交方法,这也可能是一个问题。 如何使用正确的切入点表达式记录子线程 ID 和父线程 ID?

最佳答案

您可以做的是拦截提交的任务参数并增强该任务以打印您想要的内容:

Object around(Runnable task) : call(* ExecutorService+.submit(Runnable, ..)) && args( task)
{
    final long parentID = Thread.currentThread().getId();
    Runnable newTask =  () -> {
            System.out.println("Parent Thread Id: "+ parentID);
            System.out.println("Child Thread Id: "+Thread.currentThread().getId()); //?? - how to capture child thread id?
            task.run();
    };
    return proceed(newTask);
}

一旦执行异步任务,就会打印执行该任务的线程的 id。

运行示例:

Main.java:

public class Main {
    public static void main(String[] args) {
        new Test().testExecutorService();
    }
}

测试.java:

public class Test {
    public void testExecutorService() {
        ExecutorService service = Executors.newSingleThreadExecutor();
        service.submit(() ->  System.out.println("working on the task"));
        try {
            service.awaitTermination(2, TimeUnit.SECONDS);
            service.shutdown();
        }catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
        }
    }
}

示例.aj

public aspect Example {
     
     Object around(Runnable task) : call(public Future<?> java.util.concurrent.ExecutorService+.submit(Runnable)) 
                        && args(task)
     {
         final long parentID = Thread.currentThread().getId();
         Runnable newTask =  () -> {
                 System.out.println("Parent Thread Id: "+ parentID);
                 System.out.println("Child Thread Id: "+Thread.currentThread().getId()); 
                 task.run();
         };
         return proceed(newTask);
     }
}

关于java - 如何在 Java 中使用 AspectJ 记录父级和子级的线程 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53029722/

相关文章:

java - 无法将 XML 字符串正确转换为 JAXB 对象

C++如何创建指向重载模板函数的函数指针

python - 如何获得 TkInter GUI(不是 shell 提示符)以监听来自/dev/stdin 的输入

java - 并发 JUnit 测试

java - 发现不兼容的类型 : required: default enums in annotations

java - AOP中调用和执行的区别

java - 好奇的Spring AOP异常

java - 不同的 Intent 构造函数有什么作用?

java - 如何在 Maven 中使用共享库组织项目

java - Runtime.exec() 无法运行 "su - postgres -c ' pg_dump .. .'"