java - 如何为方法实例生成唯一的哈希码?

标签 java aop aspectj

我正在使用 Aspectj 进行一些分析。

我需要唯一标识访问字段的方法实例 例如:

public class Class{ int a; int b;
public void method1(){

  setA(5);
  setB(6); 

在这种情况下,使用 AspectJ,我可以通过 setA 和 SetB 方法获得对 a 和 b 的访问。并与

Thread.currentThread().getStackTrace();

我可以知道 setA 和 setB 已经被 method1() 调用了。

方法的名称还不够,我还需要明确标识方法的实例。

例如,如果多次调用 method1,我必须辨别出对 a 和 b 的访问是由 method1 的不同实例进行的。

有什么建议可以获取方法执行的实例哈希码吗?

最佳答案

一个可能可行的简单(未经测试,使用风险自负)解决方案是为每个线程的每个方法维护一个计数器:

private static final ConcurrentHashMap<String, ConcurrentHashMap<Long, AtomicInteger>>
    COUNTERS = new ConcurrentHashMap<>();

public static int getInvocationId(String methodName, long threadId) {
    return counter(methodName, threadId).getAndIncrement();
}

private static AtomicInteger counter(String methodName, long threadId) {
    ConcurrentHashMap<Long, AtomicInteger> map = countersForMethodName(methodName);
    AtomicInteger counter = map.get(threadId);
    if (counter == null) {
        AtomicInteger newCounter = new AtomicInteger();
        counter = map.putIfAbsent(threadId, newCounter);
        if (counter == null) {
            return newCounter;
        }
    }
    return counter;
}

private static ConcurrentHashMap<Long, AtomicInteger> countersForMethodName(
    String methodName) {
    ConcurrentHashMap<Long, AtomicInteger> map = COUNTERS.get(methodName);
    if (map == null) {
        ConcurrentHashMap<Long, AtomicInteger> newMap = new ConcurrentHashMap<>();
        map = COUNTERS.putIfAbsent(methodName, newMap);
        if (map == null) {
            return newMap;
        }
    }
    return map;
}

然后,在你的建议中,像这样:

int invocationId = getInvocationId(thisJoinPoint.getSignature().getName(),
    Thread.currentThread().getId());
// do what you want with invocationId 

请注意,这依赖于在与目标方法相同的线程中执行的建议——不幸的是,我对 AspectJ 不够熟悉,无法知道这个假设是否始终成立。

警告:如果您的环境一直在创建和终止新线程,那么上面的树继续增长(本质上是内存泄漏)。如果这是一个问题,那么您将需要放入一些其他代码来定期枚举所有 Activity 线程,并从树中删除过期的条目。在这种情况下,您可能希望使用每个线程 ID 的映射,然后使用每个方法名称来提高修剪效率。

关于java - 如何为方法实例生成唯一的哈希码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7036281/

相关文章:

java - 在 Spring 中使用 AspectJ 捕获映射器方法内的 setter

java - 同步如何使 vector 线程安全?

c# - 通过 IoC 影响带有属性的 AOP;代码味还是优雅?

java - 线程在执行期间被扰乱

c - 生产代码中的面向方面的 C(而非 C++)

java - 使用 AOP 拦截私有(private)注释方法

java - 在 Maven 上使用没有 Spring 的 AspectJ

java - 如何区分生成的方法(AspectJ)

java - Applet 类加载器无法在 applet 的 jar 中找到类

java - 不区分大小写的搜索和替换