標準Java庫沒有提供足夠的方法來操作其核心類疗垛,Apache Commons Lang提供了這些額外的方法硫朦。
Apache Commons Lang為java提供了大量的幫助工具。lang API泽裳,特別是String操作方法破婆、基本數值方法、對象反射荠割、并發(fā)旺矾、創(chuàng)建和序列化以及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的靜態(tài)方法,創(chuàng)建和啟動計時器二合一stop()
停止計時器reset()
重置計時器慷吊,可以理解將計時器所有狀態(tài)數據清零為初始狀態(tài)(包括停止計時)曹抬,從而可以繼續(xù)復用這個計時器(重置之后,若要啟動計時需要重新調用start()開啟計時)
@Test
public void testStopWatch() throws InterruptedException {
// 計時測試
StopWatch stopWatch = 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()
類似與暫停計時抖韩,但是它與暫停計時的區(qū)別在于,此時計時器還是正常計時的双谆,只不過調用split()時相當于在此刻打了一個標記席揽,然后在未來某個時間可以獲取這個標記到開始計時之間的這段時間。unsplit()
與split()相反寸谜,用于清除上次split設置的標記
public void testStopWatch002() throws InterruptedException {
// 暫停計時測試
StopWatch stopWatch = 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,暫停期間不計時,恢復之后繼續(xù)計時
// 設置split停止標記
stopWatch.split();
Thread.sleep(2000);
System.out.println(stopWatch.getSplitTime()); // 這里返回split標記到開始計時時的時間間隔讲逛,4010
Thread.sleep(2000);
stopWatch.unsplit();
System.out.println(stopWatch.getTime()); // 設置split標記不影響計時,所以去除暫停的兩秒蔚鸥,總共8010
}
獲取計時結果相關API
其主要核心的幾個方法如下:
getTime()
getSplitTime()
getStartTime()
getStopTime()
formatTime()
formatSplitTime()
public void testStopWatch003() throws InterruptedException {
StopWatch stopWatch = StopWatch.createStarted();
Thread.sleep(200);
System.out.println(stopWatch.getTime()); // 205
System.out.println(stopWatch.formatTime()); // 00:00:00.205
}
實現原理
StopWatch的實現原理比較簡單止喷,核心就是通過幾個狀態(tài)和幾個變量來進行計時
/**
* The start time in nanoseconds.
*/
private long startTimeNanos;
/**
* The start time in milliseconds - nanoTime is only for elapsed time so we
* need to also store the currentTimeMillis to maintain the old
* getStartTime API.
*/
private long startTimeMillis;
/**
* The end time in milliseconds - nanoTime is only for elapsed time so we
* need to also store the currentTimeMillis to maintain the old
* getStartTime API.
*/
private long stopTimeMillis;
/**
* The stop time in nanoseconds.
*/
private long stopTimeNanos;
看start()方法
public void start() {
if (this.runningState == State.STOPPED) {
throw new IllegalStateException("Stopwatch must be reset before being restarted. ");
}
if (this.runningState != State.UNSTARTED) {
throw new IllegalStateException("Stopwatch already started. ");
}
this.startTimeNanos = System.nanoTime();
this.startTimeMillis = System.currentTimeMillis();
this.runningState = State.RUNNING;
}
可以看到調用start()的方法時混聊,記錄開始計時的時間,以及修改計時器狀態(tài)预愤,再來看
public long getNanoTime() {
if (this.runningState == State.STOPPED || this.runningState == State.SUSPENDED) {
return this.stopTimeNanos - this.startTimeNanos;
} else if (this.runningState == State.UNSTARTED) {
return 0;
} else if (this.runningState == State.RUNNING) {
return System.nanoTime() - this.startTimeNanos;
}
throw new IllegalStateException("Illegal running state has occurred.");
}
其實就是返回當前時間和開始時間的間隔咳胃,StopWatch更多的還是狀態(tài)分明,為我們封裝了一些簡單易用的API销睁,比如開始停止計時,暫投臣牵恢復計時,StopWatch可以用來代替我們代碼中經常類似下面這種計時:
long startTime = System.currentTimeMillis();
// run real action
Thread.sleep(2000);
long endTime = System.currentTimeMillis();
System.out.println("方法耗時:" + (endTime - startTime)); // 方法耗時:2006