Java计时器StopWatch实现方法代码实例
下面提供三种计时器的写法供大家参考,大家可以自行选择自己钟爱的使用。
写法一(Spring包提供的计时器):
importjava.text.NumberFormat; importjava.util.LinkedList; importjava.util.List; /** *Simplestopwatch,allowingfortimingofanumberoftasks, *exposingtotalrunningtimeandrunningtimeforeachnamedtask. * *Concealsuseof{@codeSystem.currentTimeMillis()},improvingthe *readabilityofapplicationcodeandreducingthelikelihoodofcalculationerrors. * *
Notethatthisobjectisnotdesignedtobethread-safeanddoesnot *usesynchronization. * *
Thisclassisnormallyusedtoverifyperformanceduringproof-of-concepts *andindevelopment,ratherthanaspartofproductionapplications. * *@authorRodJohnson *@authorJuergenHoeller *@authorSamBrannen *@sinceMay2,2001 */ publicclassStopWatch{ /** *Identifierofthisstopwatch. *Handywhenwehaveoutputfrommultiplestopwatches *andneedtodistinguishbetweentheminlogorconsoleoutput. */ privatefinalStringid; privatebooleankeepTaskList=true; privatefinalList
taskList=newLinkedList (); /**Starttimeofthecurrenttask*/ privatelongstartTimeMillis; /**Isthestopwatchcurrentlyrunning?*/ privatebooleanrunning; /**Nameofthecurrenttask*/ privateStringcurrentTaskName; privateTaskInfolastTaskInfo; privateinttaskCount; /**Totalrunningtime*/ privatelongtotalTimeMillis; /** *Constructanewstopwatch.Doesnotstartanytask. */ publicStopWatch(){ this(""); } /** *Constructanewstopwatchwiththegivenid. *Doesnotstartanytask. *@paramididentifierforthisstopwatch. *Handywhenwehaveoutputfrommultiplestopwatches *andneedtodistinguishbetweenthem. */ publicStopWatch(Stringid){ this.id=id; } /** *Returntheidofthisstopwatch,asspecifiedonconstruction. *@returntheid(emptyStringbydefault) *@since4.2.2 *@see#StopWatch(String) */ publicStringgetId(){ returnthis.id; } /** *DeterminewhethertheTaskInfoarrayisbuiltovertime.Setthisto *"false"whenusingaStopWatchformillionsofintervals,orthetask *infostructurewillconsumeexcessivememory.Defaultis"true". */ publicvoidsetKeepTaskList(booleankeepTaskList){ this.keepTaskList=keepTaskList; } /** *Startanunnamedtask.Theresultsareundefinedif{@link#stop()} *ortimingmethodsarecalledwithoutinvokingthismethod. *@see#stop() */ publicvoidstart()throwsIllegalStateException{ start(""); } /** *Startanamedtask.Theresultsareundefinedif{@link#stop()} *ortimingmethodsarecalledwithoutinvokingthismethod. *@paramtaskNamethenameofthetasktostart *@see#stop() */ publicvoidstart(StringtaskName)throwsIllegalStateException{ if(this.running){ thrownewIllegalStateException("Can'tstartStopWatch:it'salreadyrunning"); } this.running=true; this.currentTaskName=taskName; this.startTimeMillis=System.currentTimeMillis(); } /** *Stopthecurrenttask.Theresultsareundefinediftiming *methodsarecalledwithoutinvokingatleastonepair *{@codestart()}/{@codestop()}methods. *@see#start() */ publicvoidstop()throwsIllegalStateException{ if(!this.running){ thrownewIllegalStateException("Can'tstopStopWatch:it'snotrunning"); } longlastTime=System.currentTimeMillis()-this.startTimeMillis; this.totalTimeMillis+=lastTime; this.lastTaskInfo=newTaskInfo(this.currentTaskName,lastTime); if(this.keepTaskList){ this.taskList.add(lastTaskInfo); } ++this.taskCount; this.running=false; this.currentTaskName=null; } /** *Returnwhetherthestopwatchiscurrentlyrunning. *@see#currentTaskName() */ publicbooleanisRunning(){ returnthis.running; } /** *Returnthenameofthecurrentlyrunningtask,ifany. *@since4.2.2 *@see#isRunning() */ publicStringcurrentTaskName(){ returnthis.currentTaskName; } /** *Returnthetimetakenbythelasttask. */ publiclonggetLastTaskTimeMillis()throwsIllegalStateException{ if(this.lastTaskInfo==null){ thrownewIllegalStateException("Notasksrun:can'tgetlasttaskinterval"); } returnthis.lastTaskInfo.getTimeMillis(); } /** *Returnthenameofthelasttask. */ publicStringgetLastTaskName()throwsIllegalStateException{ if(this.lastTaskInfo==null){ thrownewIllegalStateException("Notasksrun:can'tgetlasttaskname"); } returnthis.lastTaskInfo.getTaskName(); } /** *ReturnthelasttaskasaTaskInfoobject. */ publicTaskInfogetLastTaskInfo()throwsIllegalStateException{ if(this.lastTaskInfo==null){ thrownewIllegalStateException("Notasksrun:can'tgetlasttaskinfo"); } returnthis.lastTaskInfo; } /** *Returnthetotaltimeinmillisecondsforalltasks. */ publiclonggetTotalTimeMillis(){ returnthis.totalTimeMillis; } /** *Returnthetotaltimeinsecondsforalltasks. */ publicdoublegetTotalTimeSeconds(){ returnthis.totalTimeMillis/1000.0; } /** *Returnthenumberoftaskstimed. */ publicintgetTaskCount(){ returnthis.taskCount; } /** *Returnanarrayofthedatafortasksperformed. */ publicTaskInfo[]getTaskInfo(){ if(!this.keepTaskList){ thrownewUnsupportedOperationException("Taskinfoisnotbeingkept!"); } returnthis.taskList.toArray(newTaskInfo[this.taskList.size()]); } /** *Returnashortdescriptionofthetotalrunningtime. */ publicStringshortSummary(){ return"StopWatch'"+getId()+"':runningtime(millis)="+getTotalTimeMillis(); } /** *Returnastringwithatabledescribingalltasksperformed. *Forcustomreporting,callgetTaskInfo()andusethetaskinfodirectly. */ publicStringprettyPrint(){ StringBuildersb=newStringBuilder(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); for(TaskInfotask:getTaskInfo()){ sb.append(nf.format(task.getTimeMillis())).append(""); sb.append(pf.format(task.getTimeSeconds()/getTotalTimeSeconds())).append(""); sb.append(task.getTaskName()).append("\n"); } } returnsb.toString(); } /** *Returnaninformativestringdescribingalltasksperformed *Forcustomreporting,call{@codegetTaskInfo()}andusethetaskinfodirectly. */ @Override publicStringtoString(){ StringBuildersb=newStringBuilder(shortSummary()); if(this.keepTaskList){ for(TaskInfotask:getTaskInfo()){ sb.append(";[").append(task.getTaskName()).append("]took").append(task.getTimeMillis()); longpercent=Math.round((100.0*task.getTimeSeconds())/getTotalTimeSeconds()); sb.append("=").append(percent).append("%"); } } else{ sb.append(";notaskinfokept"); } returnsb.toString(); } /** *Innerclasstoholddataaboutonetaskexecutedwithinthestopwatch. */ publicstaticfinalclassTaskInfo{ privatefinalStringtaskName; privatefinallongtimeMillis; TaskInfo(StringtaskName,longtimeMillis){ this.taskName=taskName; this.timeMillis=timeMillis; } /** *Returnthenameofthistask. */ publicStringgetTaskName(){ returnthis.taskName; } /** *Returnthetimeinmillisecondsthistasktook. */ publiclonggetTimeMillis(){ returnthis.timeMillis; } /** *Returnthetimeinsecondsthistasktook. */ publicdoublegetTimeSeconds(){ return(this.timeMillis/1000.0); } } }
下面写一个调用:
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
-----------------------------------------
00104034%task1
00204066%task2
---------------------
start开始记录,stop停止记录,然后通过StopWatch的prettyPrint方法,可直观的输出代码执行耗时,以及执行时间百分比,瞬间感觉比之前的方式高大上了一个档次。
除此之外,还有以下两个方法shortSummary,getTotalTimeMillis,查看程序执行时间。
写法二(apache.commons实现的计时器):
importjava.util.concurrent.TimeUnit; /** **
* *StopWatch
providesaconvenientAPIfortimings. **Tostartthewatch,call{@link#start()}or{@linkStopWatch#createStarted()}.Atthispointyoucan: *
*
-
*
- {@link#split()}thewatchtogetthetimewhilstthewatchcontinuesinthebackground.{@link#unsplit()}will *removetheeffectofthesplit.Atthispoint,thesethreeoptionsareavailableagain. *
- {@link#suspend()}thewatchtopauseit.{@link#resume()}allowsthewatchtocontinue.Anytimebetweenthe *suspendandresumewillnotbecountedinthetotal.Atthispoint,thesethreeoptionsareavailableagain. *
- {@link#stop()}thewatchtocompletethetimingsession. *
*Itisintendedthattheoutputmethods{@link#toString()}and{@link#getTime()}shouldonlybecalledafterstop, *splitorsuspend,howeverasuitableresultwillbereturnedatotherpoints. *
* **NOTE:Asfromv2.1,themethodsprotectagainstinappropriatecalls.Thusyoucannotnowcallstopbeforestart, *resumebeforesuspendorunsplitbeforesplit. *
* *
*1.split(),suspend(),orstop()cannotbeinvokedtwice
*2.unsplit()mayonlybecalledifthewatchhasbeensplit()
*3.resume()mayonlybecalledifthewatchhasbeensuspend()
*4.start()cannotbecalledtwicewithoutcallingreset()
*
Thisclassisnotthread-safe
* *@since2.0 */ publicclassStopWatch{ privatestaticfinallongNANO_2_MILLIS=1000000L; /** *Providesastartedstopwatchforconvenience. * *@returnStopWatchastopwatchthat'salreadybeenstarted. * *@since3.5 */ publicstaticStopWatchcreateStarted(){ finalStopWatchsw=newStopWatch(); sw.start(); returnsw; } /** *Enumerationtypewhichindicatesthestatusofstopwatch. */ privateenumState{ UNSTARTED{ @Override booleanisStarted(){ returnfalse; } @Override booleanisStopped(){ returntrue; } @Override booleanisSuspended(){ returnfalse; } }, RUNNING{ @Override booleanisStarted(){ returntrue; } @Override booleanisStopped(){ returnfalse; } @Override booleanisSuspended(){ returnfalse; } }, STOPPED{ @Override booleanisStarted(){ returnfalse; } @Override booleanisStopped(){ returntrue; } @Override booleanisSuspended(){ returnfalse; } }, SUSPENDED{ @Override booleanisStarted(){ returntrue; } @Override booleanisStopped(){ returnfalse; } @Override booleanisSuspended(){ returntrue; } }; /** **ThemethodisusedtofindoutiftheStopWatchisstarted.Asuspended *StopWatchisalsostartedwatch. *
*@returnboolean *IftheStopWatchisstarted. */ abstractbooleanisStarted(); /** **ThismethodisusedtofindoutwhethertheStopWatchisstopped.The *stopwatchwhich'snotyetstartedandexplicitlystoppedstopwatchis *consideredasstopped. *
* *@returnboolean *IftheStopWatchisstopped. */ abstractbooleanisStopped(); /** **ThismethodisusedtofindoutwhethertheStopWatchissuspended. *
* *@returnboolean *IftheStopWatchissuspended. */ abstractbooleanisSuspended(); } /** *Enumerationtypewhichindicatesthesplitstatusofstopwatch. */ privateenumSplitState{ SPLIT, UNSPLIT } /** *ThecurrentrunningstateoftheStopWatch. */ privateStaterunningState=State.UNSTARTED; /** *Whetherthestopwatchhasasplittimerecorded. */ privateSplitStatesplitState=SplitState.UNSPLIT; /** *Thestarttime. */ privatelongstartTime; /** *ThestarttimeinMillis-nanoTimeisonlyforelapsedtimesowe *needtoalsostorethecurrentTimeMillistomaintaintheold *getStartTimeAPI. */ privatelongstartTimeMillis; /** *Thestoptime. */ privatelongstopTime; /** **Constructor. *
*/ publicStopWatch(){ super(); } /** **Startthestopwatch. *
* **Thismethodstartsanewtimingsession,clearinganypreviousvalues. *
* *@throwsIllegalStateException *iftheStopWatchisalreadyrunning. */ publicvoidstart(){ if(this.runningState==State.STOPPED){ thrownewIllegalStateException("Stopwatchmustberesetbeforebeingrestarted."); } if(this.runningState!=State.UNSTARTED){ thrownewIllegalStateException("Stopwatchalreadystarted."); } this.startTime=System.nanoTime(); this.startTimeMillis=System.currentTimeMillis(); this.runningState=State.RUNNING; } /** **Stopthestopwatch. *
* **Thismethodendsanewtimingsession,allowingthetimetoberetrieved. *
* *@throwsIllegalStateException *iftheStopWatchisnotrunning. */ publicvoidstop(){ if(this.runningState!=State.RUNNING&&this.runningState!=State.SUSPENDED){ thrownewIllegalStateException("Stopwatchisnotrunning."); } if(this.runningState==State.RUNNING){ this.stopTime=System.nanoTime(); } this.runningState=State.STOPPED; } /** **Resetsthestopwatch.Stopsitifneedbe. *
* **Thismethodclearstheinternalvaluestoallowtheobjecttobereused. *
*/ publicvoidreset(){ this.runningState=State.UNSTARTED; this.splitState=SplitState.UNSPLIT; } /** **Splitthetime. *
* **Thismethodsetsthestoptimeofthewatchtoallowatimetobeextracted.Thestarttimeisunaffected, *enabling{@link#unsplit()}tocontinuethetimingfromtheoriginalstartpoint. *
* *@throwsIllegalStateException *iftheStopWatchisnotrunning. */ publicvoidsplit(){ if(this.runningState!=State.RUNNING){ thrownewIllegalStateException("Stopwatchisnotrunning."); } this.stopTime=System.nanoTime(); this.splitState=SplitState.SPLIT; } /** **Removeasplit. *
* **Thismethodclearsthestoptime.Thestarttimeisunaffected,enablingtimingfromtheoriginalstartpointto *continue. *
* *@throwsIllegalStateException *iftheStopWatchhasnotbeensplit. */ publicvoidunsplit(){ if(this.splitState!=SplitState.SPLIT){ thrownewIllegalStateException("Stopwatchhasnotbeensplit."); } this.splitState=SplitState.UNSPLIT; } /** **Suspendthestopwatchforlaterresumption. *
* **Thismethodsuspendsthewatchuntilitisresumed.Thewatchwillnotincludetimebetweenthesuspendand *resumecallsinthetotaltime. *
* *@throwsIllegalStateException *iftheStopWatchisnotcurrentlyrunning. */ publicvoidsuspend(){ if(this.runningState!=State.RUNNING){ thrownewIllegalStateException("Stopwatchmustberunningtosuspend."); } this.stopTime=System.nanoTime(); this.runningState=State.SUSPENDED; } /** **Resumethestopwatchafterasuspend. *
* **Thismethodresumesthewatchafteritwassuspended.Thewatchwillnotincludetimebetweenthesuspendand *resumecallsinthetotaltime. *
* *@throwsIllegalStateException *iftheStopWatchhasnotbeensuspended. */ publicvoidresume(){ if(this.runningState!=State.SUSPENDED){ thrownewIllegalStateException("Stopwatchmustbesuspendedtoresume."); } this.startTime+=System.nanoTime()-this.stopTime; this.runningState=State.RUNNING; } /** **Getthetimeonthestopwatch. *
* **Thisiseitherthetimebetweenthestartandthemomentthismethodiscalled,ortheamountoftimebetween *startandstop. *
* *@returnthetimeinmilliseconds */ publiclonggetTime(){ returngetNanoTime()/NANO_2_MILLIS; } /** **GetthetimeonthestopwatchinthespecifiedTimeUnit. *
* **Thisiseitherthetimebetweenthestartandthemomentthismethodiscalled,ortheamountoftimebetween *startandstop.TheresultingtimewillbeexpressedinthedesiredTimeUnitwithanyremainderroundeddown. *Forexample,ifthespecifiedunitis{@codeTimeUnit.HOURS}andthestopwatchtimeis59minutes,thenthe *resultreturnedwillbe{@code0}. *
* *@paramtimeUnittheunitoftime,notnull *@returnthetimeinthespecifiedTimeUnit,roundeddown *@since3.5 */ publiclonggetTime(finalTimeUnittimeUnit){ returntimeUnit.convert(getNanoTime(),TimeUnit.NANOSECONDS); } /** **Getthetimeonthestopwatchinnanoseconds. *
* **Thisiseitherthetimebetweenthestartandthemomentthismethodiscalled,ortheamountoftimebetween *startandstop. *
* *@returnthetimeinnanoseconds *@since3.0 */ publiclonggetNanoTime(){ if(this.runningState==State.STOPPED||this.runningState==State.SUSPENDED){ returnthis.stopTime-this.startTime; }elseif(this.runningState==State.UNSTARTED){ return0; }elseif(this.runningState==State.RUNNING){ returnSystem.nanoTime()-this.startTime; } thrownewRuntimeException("Illegalrunningstatehasoccurred."); } /** **Getthesplittimeonthestopwatch. *
* **Thisisthetimebetweenstartandlatestsplit. *
* *@returnthesplittimeinmilliseconds * *@throwsIllegalStateException *iftheStopWatchhasnotyetbeensplit. *@since2.1 */ publiclonggetSplitTime(){ returngetSplitNanoTime()/NANO_2_MILLIS; } /** **Getthesplittimeonthestopwatchinnanoseconds. *
* **Thisisthetimebetweenstartandlatestsplit. *
* *@returnthesplittimeinnanoseconds * *@throwsIllegalStateException *iftheStopWatchhasnotyetbeensplit. *@since3.0 */ publiclonggetSplitNanoTime(){ if(this.splitState!=SplitState.SPLIT){ thrownewIllegalStateException("Stopwatchmustbesplittogetthesplittime."); } returnthis.stopTime-this.startTime; } /** *Returnsthetimethisstopwatchwasstarted. * *@returnthetimethisstopwatchwasstarted *@throwsIllegalStateException *ifthisStopWatchhasnotbeenstarted *@since2.4 */ publiclonggetStartTime(){ if(this.runningState==State.UNSTARTED){ thrownewIllegalStateException("Stopwatchhasnotbeenstarted"); } //System.nanoTimeisforelapsedtime returnthis.startTimeMillis; } /** **Getsasummaryofthetimethatthestopwatchrecordedasastring. *
* **TheformatusedisISO8601-like,hours:minutes:seconds.milliseconds. *
* *@returnthetimeasaString */ @Override publicStringtoString(){ returnDurationFormatUtils.formatDurationHMS(getTime()); } /** **Getsasummaryofthesplittimethatthestopwatchrecordedasastring. *
* **TheformatusedisISO8601-like,hours:minutes:seconds.milliseconds. *
* *@returnthesplittimeasaString *@since2.1 */ publicStringtoSplitString(){ returnDurationFormatUtils.formatDurationHMS(getSplitTime()); } /** **ThemethodisusedtofindoutiftheStopWatchisstarted.Asuspended *StopWatchisalsostartedwatch. *
* *@returnboolean *IftheStopWatchisstarted. *@since3.2 */ publicbooleanisStarted(){ returnrunningState.isStarted(); } /** **ThismethodisusedtofindoutwhethertheStopWatchissuspended. *
* *@returnboolean *IftheStopWatchissuspended. *@since3.2 */ publicbooleanisSuspended(){ returnrunningState.isSuspended(); } /** **ThismethodisusedtofindoutwhethertheStopWatchisstopped.The *stopwatchwhich'snotyetstartedandexplicitlystoppedstopwatchis *consideredasstopped. *
* *@returnboolean *IftheStopWatchisstopped. *@since3.2 */ publicbooleanisStopped(){ returnrunningState.isStopped(); } }写法三(Scala函数写法):
importorg.slf4j.LoggerFactory /** *类功能描述:Debug日志追踪 * *@authorbarrycreateat18-8-29下午3:41 *@version1.0.0 */ objectDebug{ valLOGGER=LoggerFactory.getLogger(getClass) valcounter=collection.mutable.Map[String,Int]()//label->count valtimes=collection.mutable.Map[String,Long]()//label-time(ns) /** *追踪代码块 *@paramlabel标签名 *@paramcodeBlock代码块 *@tparamT返回结果类型 *@return */ deftrace[T](label:String)(codeBlock:=>T)={ valt0=System.nanoTime() valresult=codeBlock valt1=System.nanoTime() counter.get(label).map(_counter=>counter.put(label,_counter+1)).orElse(counter.put(label,1)) times.get(label).map(cost=>times.put(label,cost+(t1-t0))).orElse(times.put(label,t1-t0)) result } /** *打印日志 */ definfo():Unit={ LOGGER.warn("FinallyDone...") LOGGER.warn(s"counter:${counter}") LOGGER.warn(s"times:${times.map{case(label,cost)=>(label,cost/1000000)}}ms") } /** *重新计数 */ defreset():Unit={ counter.clear() times.clear() } }
参考下面测试代码:
java版本:
/** *@authorWangXueXingcreateat19-7-31下午1:46 *@version1.0.0 */ publicclassStopWatchDemo{ publicstaticvoidmain(String[]args){ Debug.trace("方法1调用次数及用时",()->{ try{ Thread.sleep(2000); }catch(InterruptedExceptione){ e.printStackTrace(); } return""; }); Debug.trace("方法1调用次数及用时",()->{ try{ Thread.sleep(2000); }catch(InterruptedExceptione){ e.printStackTrace(); } return""; }); Debug.trace("方法2调用次数及用时",()->{ try{ Thread.sleep(2000); }catch(InterruptedExceptione){ e.printStackTrace(); } return10; }); Debug.info(); } }
输出结果:
15:29:32.228[main]WARNtest.Debug$-FinallyDone...
15:29:32.361[main]WARNtest.Debug$-counter:Map(方法2调用次数及用时->1,方法1调用次数及用时->2)
15:29:32.364[main]WARNtest.Debug$-times:Map(方法2调用次数及用时->2000,方法1调用次数及用时->4000)ms
scala版本:
/** *@authorWangXueXingcreateat19-8-1下午3:40 *@version1.0.0 */ objectStopWatchTest{ defmain(args:Array[String]):Unit={ Debug.trace("方法1调用次数及用时")(Thread.sleep(200)) Debug.trace("方法1调用次数及用时")(Thread.sleep(200)) Debug.trace("方法2调用次数及用时")(Thread.sleep(200)) Debug.info() } }
输出结果:
15:43:58.601[main]WARNtest.stopwatch.Debug$-FinallyDone...
15:43:58.735[main]WARNtest.stopwatch.Debug$-counter:Map(方法2调用次数及用时->1,方法1调用次数及用时->2)
15:43:58.739[main]WARNtest.stopwatch.Debug$-times:Map(方法2调用次数及用时->200,方法1调用次数及用时->400)ms
对比java版本与scala版本,是不是看到scala的简洁及强大了吧!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。