Spring计时器StopWatch使用示例
StopWatch是位于org.springframework.util包下的一个工具类,通过它可方便的对程序部分代码进行计时(ms级别),适用于同步单线程代码块。
正常情况下,我们如果需要看某段代码的执行耗时,会通过如下的方式进行查看:
publicstaticvoidmain(String[]args)throwsInterruptedException{ StopWatchTest.test0(); //StopWatchTest.test1(); } publicstaticvoidtest0()throwsInterruptedException{ longstart=System.currentTimeMillis(); //dosomething Thread.sleep(100); longend=System.currentTimeMillis(); longstart2=System.currentTimeMillis(); //dosomething Thread.sleep(200); longend2=System.currentTimeMillis(); System.out.println("某某1执行耗时:"+(end-start)); System.out.println("某某2执行耗时:"+(end2-start2)); }
运行结果:
某某1执行耗时:105
某某2执行耗时:203
该种方法通过获取执行完成时间与执行开始时间的差值得到程序的执行时间,简单直接有效,但想必写多了也是比较烦人的,尤其是碰到不可描述的代码时,会更加的让人忍不住多写几个bug聊表敬意,而且该结果也不够直观,此时会想是否有一个工具类,提供了这些方法,或者自己写个工具类,刚好可以满足这种场景,并且把结果更加直观的展现出来。
首先我们的需求如下:
- 记录开始时间点
- 记录结束时间点
- 输出执行时间及各个时间段的占比
根据该需求,我们可直接使用org.springframework.util包下的一个工具类StopWatch,通过该工具类,我们对上述代码做如下改造:
publicstaticvoidmain(String[]args)throwsInterruptedException{ //StopWatchTest.test0(); StopWatchTest.test1(); } publicstaticvoidtest1()throwsInterruptedException{ StopWatchsw=newStopWatch("test"); sw.start("task1"); //dosomething Thread.sleep(100); sw.stop(); sw.start("task2"); //dosomething Thread.sleep(200); sw.stop(); System.out.println("sw.prettyPrint()~~~~~~~~~~~~~~~~~"); System.out.println(sw.prettyPrint()); }
运行结果:
sw.prettyPrint()~~~~~~~~~~~~~~~~~
StopWatch'test':runningtime(millis)=308
-----------------------------------------
ms % Taskname
-----------------------------------------
00104 034% task1
00204 066% task2
start开始记录,stop停止记录,然后通过StopWatch的prettyPrint方法,可直观的输出代码执行耗时,以及执行时间百分比,瞬间感觉比之前的方式高大上了一个档次。
除此之外,还有以下两个方法shortSummary,getTotalTimeMillis,查看程序执行时间。
运行代码及结果:
System.out.println("sw.shortSummary()~~~~~~~~~~~~~~~~~"); System.out.println(sw.shortSummary()); System.out.println("sw.getTotalTimeMillis()~~~~~~~~~~~~~~~~~"); System.out.println(sw.getTotalTimeMillis());
运行结果
sw.shortSummary()~~~~~~~~~~~~~~~~~
StopWatch'test':runningtime(millis)=308
sw.getTotalTimeMillis()~~~~~~~~~~~~~~~~~
308
其实以上内容在该工具类中实现也极其简单,通过start与stop方法分别记录开始时间与结束时间,其中在记录结束时间时,会维护一个链表类型的tasklist属性,从而使该类可记录多个任务,最后的输出也仅仅是对之前记录的信息做了一个统一的归纳输出,从而使结果更加直观的展示出来。
StopWatch优缺点:
优点:
- spring自带工具类,可直接使用
- 代码实现简单,使用更简单
- 统一归纳,展示每项任务耗时与占用总时间的百分比,展示结果直观
- 性能消耗相对较小,并且最大程度的保证了start与stop之间的时间记录的准确性
- 可在start时直接指定任务名字,从而更加直观的显示记录结果
缺点:
- 一个StopWatch实例一次只能开启一个task,不能同时start多个task,并且在该task未stop之前不能start一个新的task,必须在该taskstop之后才能开启新的task,若要一次开启多个,需要new不同的StopWatch实例
- 代码侵入式使用,需要改动多处代码
spring中StopWatch源码实现如下:
importjava.text.NumberFormat; importjava.util.LinkedList; importjava.util.List; publicclassStopWatch{ privatefinalStringid; privatebooleankeepTaskList=true; privatefinalListtaskList=newLinkedList(); privatelongstartTimeMillis; privatebooleanrunning; privateStringcurrentTaskName; privateStopWatch.TaskInfolastTaskInfo; privateinttaskCount; privatelongtotalTimeMillis; publicStopWatch(){ this.id=""; } publicStopWatch(Stringid){ this.id=id; } publicvoidsetKeepTaskList(booleankeepTaskList){ this.keepTaskList=keepTaskList; } publicvoidstart()throwsIllegalStateException{ this.start(""); } publicvoidstart(StringtaskName)throwsIllegalStateException{ if(this.running){ thrownewIllegalStateException("Can'tstartStopWatch:it'salreadyrunning"); }else{ this.startTimeMillis=System.currentTimeMillis(); this.running=true; this.currentTaskName=taskName; } } publicvoidstop()throwsIllegalStateException{ if(!this.running){ thrownewIllegalStateException("Can'tstopStopWatch:it'snotrunning"); }else{ longlastTime=System.currentTimeMillis()-this.startTimeMillis; this.totalTimeMillis+=lastTime; this.lastTaskInfo=newStopWatch.TaskInfo(this.currentTaskName,lastTime); if(this.keepTaskList){ this.taskList.add(this.lastTaskInfo); } ++this.taskCount; this.running=false; this.currentTaskName=null; } } publicbooleanisRunning(){ returnthis.running; } publiclonggetLastTaskTimeMillis()throwsIllegalStateException{ if(this.lastTaskInfo==null){ thrownewIllegalStateException("Notasksrun:can'tgetlasttaskinterval"); }else{ returnthis.lastTaskInfo.getTimeMillis(); } } publicStringgetLastTaskName()throwsIllegalStateException{ if(this.lastTaskInfo==null){ thrownewIllegalStateException("Notasksrun:can'tgetlasttaskname"); }else{ returnthis.lastTaskInfo.getTaskName(); } } publicStopWatch.TaskInfogetLastTaskInfo()throwsIllegalStateException{ if(this.lastTaskInfo==null){ thrownewIllegalStateException("Notasksrun:can'tgetlasttaskinfo"); }else{ returnthis.lastTaskInfo; } } publiclonggetTotalTimeMillis(){ returnthis.totalTimeMillis; } publicdoublegetTotalTimeSeconds(){ return(double)this.totalTimeMillis/1000.0D; } publicintgetTaskCount(){ returnthis.taskCount; } publicStopWatch.TaskInfo[]getTaskInfo(){ if(!this.keepTaskList){ thrownewUnsupportedOperationException("Taskinfoisnotbeingkept!"); }else{ return(StopWatch.TaskInfo[])this.taskList.toArray(newStopWatch.TaskInfo[this.taskList.size()]); } } publicStringshortSummary(){ return"StopWatch'"+this.id+"':runningtime(millis)="+this.getTotalTimeMillis(); } publicStringprettyPrint(){ StringBuildersb=newStringBuilder(this.shortSummary()); sb.append('\n'); if(!this.keepTaskList){ sb.append("Notaskinfokept"); }else{ sb.append("-----------------------------------------\n"); sb.append("ms%Taskname\n"); sb.append("-----------------------------------------\n"); NumberFormatnf=NumberFormat.getNumberInstance(); nf.setMinimumIntegerDigits(5); nf.setGroupingUsed(false); NumberFormatpf=NumberFormat.getPercentInstance(); pf.setMinimumIntegerDigits(3); pf.setGroupingUsed(false); StopWatch.TaskInfo[]var7; intvar6=(var7=this.getTaskInfo()).length; for(intvar5=0;var5 到此这篇关于Spring计时器StopWatch使用示例的文章就介绍到这了,更多相关Spring计时器StopWatch内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!