各位程序计时员们好!今天要介绍的是Apache Commons Lang3中的StopWatch工具类。这个工具就像编程界的"体育教练",能精确测量你的代码跑得比博尔特快还是比树懒慢,从此告别System.currentTimeMillis()的原始时代!
一、为什么需要StopWatch?
手动计时就像:
System.currentTimeMillis():要自己记录开始结束时间- 多段代码计时?准备一堆变量吧!
- 想统计总时间?拿出计算器…
而StopWatch就是你的"代码秒表":
// 石器时代计时法
long start = System.currentTimeMillis();
// 你的代码...
long cost = System.currentTimeMillis() - start;
// 智能时代计时法
StopWatch watch = StopWatch.createStarted();
// 你的代码...
long smartCost = watch.getTime();
二、StopWatch的"计时绝技"
1. 基础秒表功能
StopWatch watch = new StopWatch();
// 开始计时(两种方式)
watch.start();
// 或者
watch = StopWatch.createStarted();
// 暂停计时
watch.suspend();
// 恢复计时
watch.resume();
// 停止计时
watch.stop();
// 获取总耗时(毫秒)
long totalTime = watch.getTime();
2. 分时段统计
watch.start("初始化阶段");
// 初始化代码...
watch.stop();
watch.start("处理阶段");
// 处理逻辑...
watch.stop();
// 获取各阶段耗时
System.out.println(watch.prettyPrint());
/* 输出:
StopWatch '': running time = 123456789 ns
-----------------------------------------
ns % Task name
-----------------------------------------
045678901 037% 初始化阶段
077777888 063% 处理阶段
*/
3. 高级时间单位
// 获取不同单位的时间
long nanos = watch.getNanoTime();
long seconds = watch.getTime(TimeUnit.SECONDS);
// 自动格式化成可读字符串
String humanTime = watch.toString();
// 输出:00:00:12.345
三、实战"代码体检"
1. 性能瓶颈分析
StopWatch watch = StopWatch.createStarted();
watch.start("数据库查询");
List<User> users = userDao.queryAll();
watch.stop();
watch.start("数据处理");
processUsers(users);
watch.stop();
System.out.println("耗时分析:\n" + watch.prettyPrint());
2. 多线程任务监控
StopWatch watch = StopWatch.createStarted();
CompletableFuture<Void> task1 = CompletableFuture.runAsync(() -> {
watch.start("任务1");
// 任务1代码...
watch.stop();
});
CompletableFuture<Void> task2 = CompletableFuture.runAsync(() -> {
watch.start("任务2");
// 任务2代码...
watch.stop();
});
CompletableFuture.allOf(task1, task2).join();
System.out.println(watch.getTime() + "ms");
3. 自动化测试计时
@Test
public void testPerformance() {
StopWatch watch = StopWatch.createStarted();
// 执行测试
service.processLargeData();
assertTrue(watch.getTime() < 1000, "处理时间超过1秒!");
}
四、StopWatch的"计时法则"
- 状态管理:必须按start→stop顺序调用
- 不可重用:一个实例只能测量一个完整周期
- 线程限制:非线程安全,多线程需各自创建实例
- 精度差异:
System.nanoTime():纳秒级(但不保证绝对时间)System.currentTimeMillis():毫秒级(适合长时间测量)
五、与现代API的"竞速对比"
// Java 9+的Instant(基础计时)
Instant start = Instant.now();
// 代码...
Duration.between(start, Instant.now()).toMillis();
// Java Microbenchmark Harness (JMH)(专业基准测试)
@Benchmark
public void testMethod(Blackhole bh) {
// 基准测试代码...
}
六、版本特性一览
| 特性 | Commons Lang3 | Java 9+ | JMH |
|---|---|---|---|
| 易用性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ |
| 功能丰富度 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 测量精度 | 纳秒级 | 纳秒级 | 纳秒级+统计 |
| 多线程支持 | 需多实例 | 需多实例 | 内置支持 |
| 学习成本 | 低 | 中 | 高 |
七、总结
StopWatch就像是:
- 性能分析的"放大镜"🔍
- 代码优化的"指南针"🧭
- 开发调试的"计时器"⏱️
- 团队协作的"共同语言"💬
记住程序优化的终极真理:“如果你不能测量它,你就不能优化它!”
附赠计时场景速查表:
| 场景 | 推荐用法 | 典型输出 |
|---|---|---|
| 快速单次测量 | createStarted()+getTime() | 123ms |
| 多阶段性能分析 | start(name)+stop()+prettyPrint() | 格式化表格 |
| 高精度短时间测量 | getNanoTime() | 456789012ns |
| 自动化测试断言 | assertTrue(getTime()<1000) | 断言通过/失败 |

6187

被折叠的 条评论
为什么被折叠?



