背景
你还在用 System.currentTimeMillis… 统计耗时?

比如下面这段代码:

/**

  • @author: 栈长
  • @from: 公众号Java技术栈
    */
    @Test
    public void jdkWasteTime() throws InterruptedException {
    long start = System.currentTimeMillis();
    Thread.sleep(3000);
    System.out.printf(“耗时:%dms.”, System.currentTimeMillis() - start);
    }
    System.currentTimeMillis…这种方式统计耗时确实是用的最多的,因为它不用引入其他的 JAR 包,JDK 就能搞定,但是它用起来有几个不方便的地方:

1)需要定义初始时间值,再用当前时间进行手工计算;

2)统计多个任务的耗时比较麻烦,如果 start 赋值搞错可能还会出现逻辑问题;

有没有其他的更好的替代方案呢?答案是肯定的:StopWatch!

StopWatch
StopWatch 是一个统计耗时的工具类:

常用的 StopWatch 工具类有以下两种:

commons-lang3(Apache 提供的通用工具包)
spring-core(Spring 核心包)
虽然两个工具类的名称是一样的,但是用法大不相同,本文栈长就给大家分别演示下。

commons-lang3 提供的 StopWatch
引入依赖
commons-lang3 是 Apache 开源的通用工具包,需要额外引入 Maven 依赖:

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
简单示例
创建一个 StopWatch 实例有以下 3 种方法:

1) 使用 new 关键字

StopWatch sw = new StopWatch();
2)使用 create 工厂方法

StopWatch sw = StopWatch.create();
3)使用 createStarted 方法

StopWatch sw = StopWatch.createStarted();
这个方法不但会创建一个实例,同时还会启动计时。

来看一个简单的例子:

// 创建一个 StopWatch 实例并开始计时
StopWatch sw = StopWatch.createStarted();

// 休眠1秒
Thread.sleep(1000);

// 1002ms
System.out.printf(“耗时:%dms.\n”, sw.getTime());
更多用法
接之前的示例继续演示。

暂停计时:

// 暂停计时
sw.suspend();

Thread.sleep(1000);

// 1000ms
System.out.printf(“暂停耗时:%dms.\n”, sw.getTime());
因为暂停了,所以还是 1000ms,暂停后中间休眠的 1000 ms 不会被统计。

恢复计时:

// 恢复计时
sw.resume();

Thread.sleep(1000);

// 2001ms
System.out.printf(“恢复耗时:%dms.\n”, sw.getTime());
因为恢复了,结果是 2001 ms,恢复后中间休眠的 1000 ms 被统计了。

停止计时:

Thread.sleep(1000);

// 停止计时
sw.stop();

Thread.sleep(1000);

// 3009ms
System.out.printf(“总耗时:%dms.\n”, sw.getTime());
停止计时前休眠了 1000ms,所以结果是 3009ms,停止计时后就不能再使用暂停、恢复功能了。

重置计时:

// 重置计时
sw.reset();

// 开始计时
sw.start();

Thread.sleep(1000);

// 1000ms
System.out.printf(“重置耗时:%dms.\n”, sw.getTime());
因为重置计时了,所以重新开始计时后又变成了 1000ms。

本文所有完整示例源代码已经上传:

https://github.com/javastacks
欢迎 Star 学习,后面 Java 示例都会在这上面提供!

Spring 提供的 StopWatch
来看一个简单的例子:

// 创建一个 StopWatch 实例
StopWatch sw = StopWatch(“公众号Java技术栈:测试耗时”);

// 开始计时
sw.start(“任务1”);

// 休眠1秒
Thread.sleep(1000);

// 停止计时
sw.stop();

// 1002ms
System.out.printf(“任务1耗时:%d%s.\n”, sw.getLastTaskTimeMillis(), “ms”);
Spring 创建实例的方法就是 new,开始计时,以及获取时间需要手动 start、stop。

继续再新增 2 个任务:

Thread.sleep(1000);

sw.start(“任务2”);
Thread.sleep(1100);
sw.stop();

// 1100ms.
System.out.printf(“任务2耗时:%d%s.\n”, sw.getLastTaskTimeMillis(), “ms”);

sw.start(“任务3”);
Thread.sleep(1200);
sw.stop();

// 1203ms.
System.out.printf(“任务3耗时:%d%s.\n”, sw.getLastTaskTimeMillis(), “ms”);

// 3.309373456s.
System.out.printf(“任务数量:%s,总耗时:%ss.\n”, sw.getTaskCount(), sw.getTotalTimeSeconds());
Spring 一个重要的亮点是支持格式化打印结果:

System.out.println(sw.prettyPrint());
来看最后的输出结果:


不过有一点不友好的是,格式化结果显示的是纳秒,而且不能修改。。

实现原理
分别来看下 commons-lang3 和 Spring 的核心源码:


其实也都是利用了 JDK 中的 System 系统类去实现的,做了一系列封装而已。

总结
commons-lang3 工具包和 Spring 框架中的 StopWatch 都能轻松完成多个任务的计时以及总耗时,再也不要用手工计算耗时的方式了,手动计算如果 start 赋值错误可能还会出错。

当然,以上两个 StopWatch 的功能也远不止栈长介绍的,栈长介绍的这些已经够用了,更多的可以深入研究。

本文所有完整示例源代码已经上传:

https://github.com/javastacks
欢迎 Star 学习,后面 Java 示例都会在这上面提供!

总结一下这两种计时工具类优缺点:

1)commons-lang3 中的 StopWatch 的用法比 Spring 中的要更简单一些;

2)commons-lang3 中的 StopWatch 功能比 Spring 中的要更灵活、更强大一些,支持暂停、恢复、重置等功能;

3)Spring 提供每个子任务名称,以及按格式化打印结果功能,针对多任务统计时更好一点;

综上所述,个人推荐使用 commons-lang3 工具包中的,更灵活、更强大,如果不想额外引入包,也可以考虑 Spring 中的,根据自己的系统需求定。

所以,别再用 System.currentTimeMillis… 统计耗时了,太 low,赶紧分享转发下吧,规范起来!

好了,今天的分享就到这里了,后面栈长会分享更多好玩的 Java 技术和最新的技术资讯,关注公众号Java技术栈第一时间推送,我也将主流 Java 面试题和参考答案都整理好了,在公众号后台回复关键字 “面试” 进行刷题。

更多相关文章

  1. Android计时器Chronometer的使用
  2. Java/Android倒计时(开始,暂停,恢复,停止)
  3. Android的Handler用法(定时)
  4. android扇形菜单
  5. Android验证码倒计时功能实现
  6. Android(安卓)CountDownTimer倒计时器的使用
  7. Android(安卓)studio爬取网页
  8. android批量插入数据效率对比
  9. android 按钮倒计时读秒

随机推荐

  1. Android之布局属性归纳
  2. Android Framework(I)Android Spring Jso
  3. Android中layout属性大全
  4. android总结
  5. Android 自学杂记
  6. Android Studio中快速替换styles的正则表
  7. Android 网络编程 目录
  8. Android常用UI界面设计及国际化
  9. Android输入系统(三):加载按键映射
  10. Android:(10)如何安装卸载的应用程序解析