StopWatch 是 Spring 框架提供的一个简单而强大的计时工具类,用于测量代码块的执行时间。它特别适合在开发阶段进行性能分析、调试和优化。
基本使用方法
java
// 创建 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.1
stopWatch.start("矩阵运算");
Thread.sleep(300);
stopWatch.stop();
// 子任务3.2
stopWatch.start("向量处理");
Thread.sleep(200);
stopWatch.stop();
} finally {
stopWatch.stop(); // 停止复杂计算任务
}
获取总耗时
java
// 毫秒
long totalTimeMillis = stopWatch.getTotalTimeMillis();
// 秒
double totalTimeSeconds = stopWatch.getTotalTimeSeconds();
// 纳秒
long totalTimeNanos = stopWatch.getTotalTimeNanos();
获取单个任务耗时
java
// 获取所有任务信息
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);
}
格式化输出
java
// 简洁输出
System.out.println(stopWatch.shortSummary());
// 格式化表格输出
System.out.println(stopWatch.prettyPrint());
输出格式如下
text
StopWatch '性能分析': running time = 2200943100 ns
---------------------------------------------
ns % Task name
---------------------------------------------
0500664900 023% 任务1
1199987500 055% 任务2
0500290700 023% 复杂计算
高级用法
条件计时(可实现测试环境记时而生产环境不记时)
java
public class ConditionalStopWatch extends StopWatch {
private final boolean enabled;
public ConditionalStopWatch(String id, boolean enabled) {
super(id);
this.enabled = enabled;
}
@Override
public void start(String taskName) throws IllegalStateException {
if (enabled) super.start(taskName);
}
@Override
public void stop() throws IllegalStateException {
if (enabled) super.stop();
}
}
// 使用示例(仅在开发环境启用)
boolean isDevMode = true;
ConditionalStopWatch devWatch = new ConditionalStopWatch("开发监控", isDevMode);
使用注意事项
-
合理命名任务:使用清晰的任务名称(如 "用户查询"、"订单处理")
-
避免生产环境使用:StopWatch 主要用于开发调试,生产环境考虑专业 APM 工具
-
注意嵌套任务:确保 start/stop 调用成对出现
-
使用 try-finally:确保在异常情况下也能停止计时
完整示例
java
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();
}
}