StopWatch监控Java代码运行时间
一、背景
有时我们在做开发的时候需要记录每个任务执行时间,或者记录一段代码执行时间,最简单的方法就是打印当前时间与执行完时间的差值,一般我们检测某段代码执行的时间,都是以如下方式来进行的:
1 | public static void main(String[] args) { |
事实上该方法通过获取执行完成时间与执行开始时间的差值得到程序的执行时间,简单直接有效,但想必写多了也是比较烦人的,尤其是碰到不可描述的代码时,会更加的让人忍不住多写几个bug聊表敬意,而且如果想对执行的时间做进一步控制,则需要在程序中很多地方修改。
此时会想是否有一个工具类,提供了这些方法,刚好可以满足这种场景?
我们可以利用已有的工具类中的秒表,常见的秒表工具类有 org.springframework.util.StopWatch、org.apache.commons.lang.time.StopWatch
以及谷歌提供的guava中的秒表(这个我没怎么用过)
这里重点讲下基于spring、Apache的使用
二、spring 用法
2.1 初遇
StopWatch 是位于 org.springframework.util
包下的一个工具类,通过它可方便的对程序部分代码进行计时(ms级别),适用于同步单线程代码块。简单总结一句,Spring提供的计时器StopWatch对于秒、毫秒为单位方便计时的程序,尤其是单线程、顺序执行程序的时间特性的统计输出支持比较好。
也就是说假如我们手里面有几个在顺序上前后执行的几个任务,而且我们比较关心几个任务分别执行的时间占用状况,希望能够形成一个不太复杂的日志输出,StopWatch提供了这样的功能。而且Spring的StopWatch基本上也就是仅仅为了这样的功能而实现。
想要使用它,首先你需要在你的 Maven 中引入 Spring 核心包,当然 Spring MVC 和 Spring Boot 都已经自动引入了该包:
1 | <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> |
对一切事物的认知,都是从使用开始,那就先来看看它的用法,会如下所示:
1 | public static void main(String[] args) throws InterruptedException { |
如图所示,StopWatch 不仅正确记录了上个任务的执行时间,并且在最后还可以给出精确的任务执行时间(纳秒级别)和耗时占比,这或许就会比我们自己输出要优雅那么一些。
2.2 源码
老规矩,由浅入深。看完用法,我们来看看源码。先看下组成 StopWatch 的属性
1 | public class StopWatch { |
接下来,我们看一下StopWatch类的构造器和一些关键方法
2.3 注意事项
- StopWatch对象不是设计为线程安全的,并且不使用同步。
- 一个StopWatch实例一次只能开启一个task,不能同时start多个task
- 在该task还没stop之前不能start一个新的task,必须在该task stop之后才能开启新的task
- 若要一次开启多个,需要new不同的StopWatch实例
三、apache 用法
StopWath是 apache commons lang3
包下的一个任务执行时间监视器,与我们平时常用的秒表的行为比较类似,我们先看一下其中的一些重要方法:
1 | <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> |
Apache提供的这个任务执行监视器功能丰富强大,灵活性强,如下经典实用案例:
1 | public static void main(String[] args) throws InterruptedException { |