在近期工作中遇到个性能测试的打印的问题,由于log4j中如果在多线程中,打印的无规律性(哪个线程先到就先打印),在多个线程中会出现的问题是,在action-service-dao 层模式中,如果想查看单个线程在action-service-dao 三层之间的消化时间,是很难查到的,因为它们是无规律打印的。为了解决这个问题,可以利用ThreadLocal 这个线程变量类,关于这个类的使用已经很广泛了,在Spring中事务处理,hibernate的session处理等,这个类的功能分析,可查看ThreadLocal源码分析 。其实在struts2中,已经使用了这个功能用于记录action 的各模块的性能统计了。我也只是在它的基础上修改一些,当然基本大部分是copy 源码的。。
现在来看看实现的效果:
2010-05-10 18:06:16,359 INFO (TimeLoggerStack:155) - [0ms] - util.timelogger.LoggerTest (:12) [0ms] - test1 [0ms] - test2 (util.timelogger.LoggerTest:35) [0ms] - util.timelogger.LoggerTest [0ms] - test2 (util.timelogger.LoggerTest:35)
测试类:
package util.timelogger;
import util.timelogger.TimerLoggerStack.ProfilingBlock;
/**
* 测试
* @author zhxing
*
*/
public class LoggerTest {
public static void main(String[] args) {
TimerLoggerStack.setActive(true);
TimerLoggerStack.push(LoggerTest.class);
test1();
TimerLoggerStack.pop(LoggerTest.class);
}
public static void test1() {
// System.out.println(Thread.currentThread().getStackTrace()[1].getLineNumber());
TimerLoggerStack.push("test1");
test2();
TimerLoggerStack.pop("test1");
TimerLoggerStack.profile(LoggerTest.class, new ProfilingBlock() {
@Override
public Object doProfiling() {
test2();
return null;
}
});
}
public static void test2() {
TimerLoggerStack.push("test2",LoggerTest.class);
TimerLoggerStack.pop("test2");
}
}
代码的实现很简单,上面也说了,主要是应用了回调模式和ThreadLocal 类的功能。有兴趣的可查看下面的代码。