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

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

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

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

  setA(5);
  setB(6); 

在使用AspectJ的情况下,我可以获得setA和SetB方法对a的访问和对b的访问.与

Thread.currentThread().getStackTrace();

我可以知道setA()调用了setA和setB.

方法的名称是不够的我还需要单一地识别方法的实例.

例如,如果多次调用method1,我必须识别对method1的不同实例的访问和对b的访问.

任何建议如何获取方法执行的实例哈希码?

解决方法:

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

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不太熟悉,不知道这个假设是否总是成立.

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

上一篇:java – 任何将所有IOExceptions包装到RuntimeException的方法吗?


下一篇:Gradle 1.0 Spring AspectJ构建问题