标准Java库没有提供足够的方法来操作其核心类,Apache Commons Lang提供了这些额外的方法。
Apache Commons Lang为java提供了大量的帮助工具。lang API,特别是String操作方法、基本数值方法、对象反射、并发、创建和序列化以及System属性。此外,它还包含对java.util.Date的基本增强,以及一系列专门用于帮助构建方法的实用工具,如hashCode、toString和equals。
-- 来自官方简介http://commons.apache.org/proper/commons-lang/index.html
StopWatch介绍及核心API
StopWatch是位于org.apache.commons.lang3.time下的和时间有关的线程非安全的工具类。StopWatch为计时提供了很方便的API。StopWatch中提供的API都是成对使用的,比如有开始就有停止,有暂停就有恢复。
启动、停止、重置计时相关API
start() 启动计时
createStarted() StopWatch的静态方法,创建和启动计时器二合一
stop() 停止计时器
reset() 重置计时器,可以理解将计时器所有状态数据清零为初始状态(包括停止计时),从而可以继续复用这个计时器(重置之后,若要启动计时需要重新调用start()开启计时)
@TestpublicvoidtestStopWatch()throwsInterruptedException{//计时测试StopWatchstopWatch=StopWatch.createStarted();Thread.sleep(2000);System.out.println(stopWatch.getTime());//2001//重置测试,重置之后,不再计时stopWatch.reset();Thread.sleep(2000);System.out.println(stopWatch.getTime());//3005//重新启动重置之后的计时器stopWatch.start();Thread.sleep(2000);System.out.println(stopWatch.getTime());//2005//停止计时测试stopWatch.stop();Thread.sleep(2000);System.out.println(stopWatch.getTime());//2001}
暂停、恢复计时相关API
suspend() 暂停计时,此时计时器也将停止
resume() 恢复计时,计时器重新开始计时
split() 类似与暂停计时,但是它与暂停计时的区别在于,此时计时器还是正常计时的,只不过调用split()时相当于在此刻打了一个标记,然后在未来某个时间可以获取这个标记到开始计时之间的这段时间。
unsplit() 与split()相反,用于清除上次split设置的标记
publicvoidtestStopWatch002()throwsInterruptedException{//暂停计时测试StopWatchstopWatch=StopWatch.createStarted();Thread.sleep(2000);stopWatch.suspend();Thread.sleep(2000);System.out.println(stopWatch.getTime());//2005,暂停之后不再计时,所以暂停之后的2s不会计入//恢复计时stopWatch.resume();Thread.sleep(2000);System.out.println(stopWatch.getTime());//4010,暂停期间不计时,恢复之后继续计时//设置split停止标记stopWatch.split();Thread.sleep(2000);System.out.println(stopWatch.getSplitTime());//这里返回split标记到开始计时时的时间间隔,4010Thread.sleep(2000);stopWatch.unsplit();System.out.println(stopWatch.getTime());//设置split标记不影响计时,所以去除暂停的两秒,总共8010}
获取计时结果相关API
其主要核心的几个方法如下:
getTime()
getSplitTime()
getStartTime()
getStopTime()
formatTime()
formatSplitTime()
publicvoidtestStopWatch003()throwsInterruptedException{StopWatchstopWatch=StopWatch.createStarted();Thread.sleep(200);System.out.println(stopWatch.getTime());//205System.out.println(stopWatch.formatTime());//00:00:00.205}
实现原理
StopWatch的实现原理比较简单,核心就是通过几个状态和几个变量来进行计时
/***Thestarttimeinnanoseconds.*/privatelongstartTimeNanos;/***Thestarttimeinmilliseconds-nanoTimeisonlyforelapsedtimesowe*needtoalsostorethecurrentTimeMillistomaintaintheold*getStartTimeAPI.*/privatelongstartTimeMillis;/***Theendtimeinmilliseconds-nanoTimeisonlyforelapsedtimesowe*needtoalsostorethecurrentTimeMillistomaintaintheold*getStartTimeAPI.*/privatelongstopTimeMillis;/***Thestoptimeinnanoseconds.*/privatelongstopTimeNanos;
看start()方法
publicvoidstart(){if(this.runningState==State.STOPPED){thrownewIllegalStateException("Stopwatchmustberesetbeforebeingrestarted.");}if(this.runningState!=State.UNSTARTED){thrownewIllegalStateException("Stopwatchalreadystarted.");}this.startTimeNanos=System.nanoTime();this.startTimeMillis=System.currentTimeMillis();this.runningState=State.RUNNING;}
可以看到调用start()的方法时,记录开始计时的时间,以及修改计时器状态,再来看
publiclonggetNanoTime(){if(this.runningState==State.STOPPED||this.runningState==State.SUSPENDED){returnthis.stopTimeNanos-this.startTimeNanos;}elseif(this.runningState==State.UNSTARTED){return0;}elseif(this.runningState==State.RUNNING){returnSystem.nanoTime()-this.startTimeNanos;}thrownewIllegalStateException("Illegalrunningstatehasoccurred.");}
其实就是返回当前时间和开始时间的间隔,StopWatch更多的还是状态分明,为我们封装了一些简单易用的API,比如开始停止计时,暂停恢复计时,StopWatch可以用来代替我们代码中经常类似下面这种计时:
longstartTime=System.currentTimeMillis();//runrealactionThread.sleep(2000);longendTime=System.currentTimeMillis();System.out.println("方法耗时:"+(endTime-startTime));//方法耗时:2006