Spring 工具类:StopWatch
StopWatch 是 Spring 框架提供的一个简单而强大的计时工具类,用于测量代码块的执行时间。它特别适合在开发阶段进行性能分析、调试和优化。
基本使用方法
// 创建 StopWatch 实例(可指定 ID)
StopWatch stopWatch = new StopWatch("性能分析");// 任务1 开始计时
stopWatch.start("任务1");
try {Thread.sleep(500); // 模拟任务执行
} finally {stopWatch.stop(); // 任务1 计时结束
}// 任务2 开始计时
stopWatch.start("任务2");
try {Thread.sleep(1200);
} finally {stopWatch.stop(); // 任务2 计时结束
}// 任务3(嵌套任务)
stopWatch.start("复杂计算");
try {// 子任务3.1stopWatch.start("矩阵运算");Thread.sleep(300);stopWatch.stop();// 子任务3.2stopWatch.start("向量处理");Thread.sleep(200);stopWatch.stop();
} finally {stopWatch.stop(); // 停止复杂计算任务
}
获取总耗时
// 毫秒
long totalTimeMillis = stopWatch.getTotalTimeMillis();// 秒
double totalTimeSeconds = stopWatch.getTotalTimeSeconds();// 纳秒
long totalTimeNanos = stopWatch.getTotalTimeNanos();
获取单个任务耗时
// 获取所有任务信息
StopWatch.TaskInfo[] tasks = stopWatch.getTaskInfo();
for (StopWatch.TaskInfo task : tasks) {System.out.printf("任务: %-15s 耗时: %6dms (%.1f%%)%n", task.getTaskName(), task.getTimeMillis(), (double) task.getTimeMillis() / totalTimeMillis * 100);
}
格式化输出
// 简洁输出
System.out.println(stopWatch.shortSummary());// 格式化表格输出
System.out.println(stopWatch.prettyPrint());
输出格式如下
StopWatch '性能分析': running time = 2200943100 ns
---------------------------------------------
ns % Task name
---------------------------------------------
0500664900 023% 任务1
1199987500 055% 任务2
0500290700 023% 复杂计算
高级用法
条件计时(可实现测试环境记时而生产环境不记时)
public class ConditionalStopWatch extends StopWatch {private final boolean enabled;public ConditionalStopWatch(String id, boolean enabled) {super(id);this.enabled = enabled;}@Overridepublic void start(String taskName) throws IllegalStateException {if (enabled) super.start(taskName);}@Overridepublic void stop() throws IllegalStateException {if (enabled) super.stop();}
}// 使用示例(仅在开发环境启用)
boolean isDevMode = true;
ConditionalStopWatch devWatch = new ConditionalStopWatch("开发监控", isDevMode);
使用注意事项
-
合理命名任务:使用清晰的任务名称(如 “用户查询”、“订单处理”)
-
避免生产环境使用:StopWatch 主要用于开发调试,生产环境考虑专业 APM 工具
-
注意嵌套任务:确保 start/stop 调用成对出现
-
使用 try-finally:确保在异常情况下也能停止计时
完整示例
public class StopWatchDemo {public static void main(String[] args) throws InterruptedException {// 创建 StopWatch 实例StopWatch stopWatch = new StopWatch("API 性能分析");// 模拟API处理流程stopWatch.start("请求解析");Thread.sleep(80);stopWatch.stop();stopWatch.start("身份验证");Thread.sleep(120);stopWatch.stop();stopWatch.start("业务处理");processBusinessLogic(stopWatch);stopWatch.stop();stopWatch.start("响应构建");Thread.sleep(60);stopWatch.stop();// 输出结果System.out.println("\n===== 性能分析报告 =====");System.out.println(stopWatch.shortSummary());System.out.println(stopWatch.prettyPrint());// 获取详细信息System.out.println("总耗时: " + stopWatch.getTotalTimeMillis() + "ms");System.out.println("最耗时的任务: " + stopWatch.getLastTaskName());}private static void processBusinessLogic(StopWatch parentWatch) throws InterruptedException {parentWatch.start("数据库查询");Thread.sleep(200);parentWatch.stop();parentWatch.start("数据转换");Thread.sleep(150);parentWatch.stop();parentWatch.start("缓存处理");Thread.sleep(100);parentWatch.stop();}
}