java 的工具使用注解 monitor/log/report 线程访问给定方法?
Tool for java that uses annotation to monitor/log/report threads accessing given method?
上下文:
我为游戏创建了一个小型 (java) 多线程服务器。尽管我尽最大努力遵循最佳实践,但事实证明,一些本应仅从一个线程调用的方法被从 2 个或更多线程调用。经过调试和分析,我已经设法 "fix" 我的设计,但我想知道:
问题:
是否有一种工具(或者如果没有 - 是否有可能(以及如何)开发)允许您使用 @SingleThread
或 @ThreadCount(2)
或 [=14 等注释标记某些方法=] 其中 counts/monitors/logs 访问这些方法如:
@SingleThread
- 检查此方法是否始终仅由线程访问
@ThreadCount(2)
- 恰好被两个线程访问
@ThreadNameLike
- 仅由名称与模式匹配的线程访问
想法是对程序进行 TEST 运行 并至少获取违反注释条件的日志记录。
我在想也许 AspectJ 可以通过它的切入点在某种程度上完成这项工作,但后来我意识到一些类似于 Dagger / Dagger2 的方法会更好,即当你想测试你的服务器时,你将不得不转向在注释处理器上(假设我们称它为 "SafetyFirst"),它将生成包含监控代码的适配器(包装器?)类。然后你将 运行 服务器,运行 一些负载测试,然后检查日志是否有违规(或者在理想情况下 - 获取报告文件)。
我完全意识到这样的工具:
- 不会 100% 覆盖所有潜在案例;
- 将 mask/trigger heisenbugs
- 会降低被检查程序的速度
但至少它可以作为一个预警系统,清楚地宣传违反预期设计的行为。
我使用了一个类似的测试 AspectJ
加载时间编织来打印我的包中的所有函数调用。
加载时织入的最佳方式是不要像编译时织入那样弄脏 类。当您从 运行 命令中删除 -javaagent:<path to aspectj lib>
和您的自定义 astpect 库类路径条目时。然后一切都过去了,清楚了。
我进行了一些更改并实施了涵盖您要求的@ThreadCount 功能的测试。您需要下载并安装 AspectJ。
请查看代码片段:
aspect Profile {
private static Map<String, AtomicInteger> counterMap = new HashMap<String, AtomicInteger>();
pointcut threadCountPc(test.ThreadCount tc) : execution(* test..*(..)) && @annotation(tc);
Object around(test.ThreadCount tc) : threadCountPc(tc) {
String signature = thisJoinPointStaticPart.getSignature().toString();
AtomicInteger counter = getCounter(signature);
int currentValue = counter.incrementAndGet();
if (currentValue >= tc.value()){
System.out.println("[Thread Name:" + Thread.currentThread().getName() +
"] Method Name:" + signature + ", threadCount:" + currentValue + " exceeds " + tc.value());
}
try{
return proceed(tc);
}finally{
counter.decrementAndGet();
}
}
private static AtomicInteger getCounter(String methodName){
AtomicInteger value = counterMap.get(methodName);
if (value == null){
synchronized (counterMap){
value = counterMap.get(methodName);
if (value == null){
value = new AtomicInteger(0);
counterMap.put(methodName, value);
}
}
}
return value;
}
}
编译:"C:/aspectj1.8/bin/ajc.bat" profile_ft.aj -cp C:/aspectj1.8/lib/aspectjrt.jar;../test/. -1.6 -outxml -outjar profile_ft.jar
运行: java -javaagent:C:/aspectj1.8/lib/aspectjweaver.jar -cp aspectj/profile_ft.jar;test test.Test1
上下文:
我为游戏创建了一个小型 (java) 多线程服务器。尽管我尽最大努力遵循最佳实践,但事实证明,一些本应仅从一个线程调用的方法被从 2 个或更多线程调用。经过调试和分析,我已经设法 "fix" 我的设计,但我想知道:
问题:
是否有一种工具(或者如果没有 - 是否有可能(以及如何)开发)允许您使用 @SingleThread
或 @ThreadCount(2)
或 [=14 等注释标记某些方法=] 其中 counts/monitors/logs 访问这些方法如:
@SingleThread
- 检查此方法是否始终仅由线程访问@ThreadCount(2)
- 恰好被两个线程访问@ThreadNameLike
- 仅由名称与模式匹配的线程访问
想法是对程序进行 TEST 运行 并至少获取违反注释条件的日志记录。
我在想也许 AspectJ 可以通过它的切入点在某种程度上完成这项工作,但后来我意识到一些类似于 Dagger / Dagger2 的方法会更好,即当你想测试你的服务器时,你将不得不转向在注释处理器上(假设我们称它为 "SafetyFirst"),它将生成包含监控代码的适配器(包装器?)类。然后你将 运行 服务器,运行 一些负载测试,然后检查日志是否有违规(或者在理想情况下 - 获取报告文件)。
我完全意识到这样的工具:
- 不会 100% 覆盖所有潜在案例;
- 将 mask/trigger heisenbugs
- 会降低被检查程序的速度
但至少它可以作为一个预警系统,清楚地宣传违反预期设计的行为。
我使用了一个类似的测试 AspectJ
加载时间编织来打印我的包中的所有函数调用。
加载时织入的最佳方式是不要像编译时织入那样弄脏 类。当您从 运行 命令中删除 -javaagent:<path to aspectj lib>
和您的自定义 astpect 库类路径条目时。然后一切都过去了,清楚了。
我进行了一些更改并实施了涵盖您要求的@ThreadCount 功能的测试。您需要下载并安装 AspectJ。
请查看代码片段:
aspect Profile {
private static Map<String, AtomicInteger> counterMap = new HashMap<String, AtomicInteger>();
pointcut threadCountPc(test.ThreadCount tc) : execution(* test..*(..)) && @annotation(tc);
Object around(test.ThreadCount tc) : threadCountPc(tc) {
String signature = thisJoinPointStaticPart.getSignature().toString();
AtomicInteger counter = getCounter(signature);
int currentValue = counter.incrementAndGet();
if (currentValue >= tc.value()){
System.out.println("[Thread Name:" + Thread.currentThread().getName() +
"] Method Name:" + signature + ", threadCount:" + currentValue + " exceeds " + tc.value());
}
try{
return proceed(tc);
}finally{
counter.decrementAndGet();
}
}
private static AtomicInteger getCounter(String methodName){
AtomicInteger value = counterMap.get(methodName);
if (value == null){
synchronized (counterMap){
value = counterMap.get(methodName);
if (value == null){
value = new AtomicInteger(0);
counterMap.put(methodName, value);
}
}
}
return value;
}
}
编译:"C:/aspectj1.8/bin/ajc.bat" profile_ft.aj -cp C:/aspectj1.8/lib/aspectjrt.jar;../test/. -1.6 -outxml -outjar profile_ft.jar
运行: java -javaagent:C:/aspectj1.8/lib/aspectjweaver.jar -cp aspectj/profile_ft.jar;test test.Test1