最近在看Springboot源码中,发现了一个有趣又有用的简单小工具,特此推荐下。
如下图,springboot中用StopWatch的start方法跟stop方法包含住了整个Springboot的启动过程。
StopWatch:秒表,跑表的意思,我们按字面意思大概就可以推测出它是用来计算时间,监控时间之类的。
一般在开发工程中,我们统计代码运行耗时都是通过自己敲代码来完成的,例如下面:
用StopWatch后,我们可以这样写,如下图:
单个计时看起来差别不大,但如果在单个线程我们要多次计算执行时间,那么StopWatch工具就更方便了,如下例子:
public static void main1(String[] args) { StopWatch stopWatch = new StopWatch(); for (int i = 0; i < 5; i++) { stopWatch.start("stopWatch"+i); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } stopWatch.stop(); } System.out.println("stopWatch TaskNum:"+stopWatch.getTaskCount()); System.out.println("总耗时:"+stopWatch.getTotalTimeSeconds()+"秒"); for (StopWatch.TaskInfo taskInfo : stopWatch.getTaskInfo()) { System.out.println(taskInfo.getTaskName()+"耗时:"+taskInfo.getTimeSeconds()+"秒"); } }
接下来,我们看看StopWatch源码是怎么写的。
看看start,stop方法:
public void start() throws IllegalStateException { start(""); } public void start(String taskName) throws IllegalStateException { if (this.currentTaskName != null) { throw new IllegalStateException("Can't start StopWatch: it's already running"); } this.currentTaskName = taskName; this.startTimeNanos = System.nanoTime(); } public void stop() throws IllegalStateException { if (this.currentTaskName == null) { throw new IllegalStateException("Can't stop StopWatch: it's not running"); } long lastTime = System.nanoTime() - this.startTimeNanos; this.totalTimeNanos += lastTime; this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime); if (this.keepTaskList) { this.taskList.add(this.lastTaskInfo); } ++this.taskCount; this.currentTaskName = null; }
在start时,先判断currentTaskName当前任务名是否为空来判断是否有任务正在计时中,如果有则抛出异常,这说明StopWatch只支持线性计算,不适用与多次start然后再多次stop,只能start一次后再stop一次来计算多个任务时间。
在start中记录了开始时间,在stop中记录了结束时间,并把当前任务名称跟耗时封装成TaskInfo对象保存到数组keepTaskList里,以此来支持计算多次任务。
顺带提一下,在stop中,StopWatch还特意定义了一个totalTimeNanos变量来记录总耗时,然后在getTotalTime方法中直接用totalTimeNanos变量来处理返回,而不是循环遍历数组来获取计算总耗时,这是小小的通过空间换时间的编码思维。
End~~~