Java计时新姿势StopWatch详解
一、最简单的计时
在我们的程序中不免需要对某一个运算或者方法进行计时,以便我们来观察该运算或方法是否符合我们的预期,所以在我们刚开始接触Java的时候都能写出类似下面这样的代码来计时:
publicstaticvoidmain(String[]args){ LongstartTime=System.currentTimeMillis(); doSomeThing(); LongendTime=System.currentTimeMillis(); LongelapsedTime=(endTime-startTime)/1000; System.out.println("总共耗时:"+elapsedTime+"s"); } //用于模拟一些操作 privatestaticvoiddoSomeThing(){ try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } }
事实上这样也并没有什么问题,并且也能够运行的很好,但是有一点不太好的就是,自己关注了太多输出的信息,下面我们来认识一种更优雅的一种计时方式;
二、StopWatch类
想要使用它,首先你需要在你的Maven中引入Spring核心包,当然SpringMVC和SpringBoot都已经自动引入了该包:
org.springframework spring-core ${spring.version}
现在我们计时的姿势或许就会变成以下这样:
publicstaticvoidmain(String[]args){ StopWatchclock=newStopWatch(); clock.start("开始任务一"); doSomeThing(); clock.stop(); clock.start("开始任务二"); doSomeThing(); clock.stop(); System.out.println(clock.prettyPrint()); } //用于模拟一些操作 privatestaticvoiddoSomeThing(){ try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } }
在最后我们使用StopWatch类自带的prettyPrint()方法类格式化我们的输出,运行程序你会发现你的程序输出了这样的东西:
StopWatch'':runningtime(millis)=2009 ----------------------------------------- ms%Taskname ----------------------------------------- 01005050%开始任务一 01004050%开始任务二
不仅有总用时,还有每个任务分别的占用时间和占用时间的百分比,这或许就会比我们自己输出要优雅那么一些;
StopWatch类是怎么实现的呢?
当你戳开StopWatch的源码,你会在总共不到200行的代码里看到熟悉的东西:
publicvoidstart(StringtaskName)throwsIllegalStateException{ if(this.currentTaskName!=null){ thrownewIllegalStateException("Can'tstartStopWatch:it'salreadyrunning"); }else{ this.currentTaskName=taskName; this.startTimeMillis=System.currentTimeMillis(); } } publicvoidstop()throwsIllegalStateException{ if(this.currentTaskName==null){ 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.currentTaskName=null; } }
你会发现该类使用LinkedList实现了一个叫做taskList的队列,然后每一次开始同样也是使用System.currentTimeMillis()方法来获取时间,每次除了计算耗时也会构建一个描述当前任务的TaskInfo对象,并把它放入taskList队列中。
当执行prettyPrint()方法的时候,就从taskList队列中依次取出任务,然后做些格式化的操作:
publicStringshortSummary(){ return"StopWatch'"+this.getId()+"':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[]var4=this.getTaskInfo(); intvar5=var4.length; for(intvar6=0;var6摁,新姿势get√。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。