Guava 中的 Stopwatch 是什么?
點(diǎn)擊上方藍(lán)色“Stephen”,選擇“設(shè)為星標(biāo)”
來源:https://my.oschina.net/lowkeysoft/blog/1595755
Stopwatch 解釋為計(jì)時器,又稱秒表、停表,很明顯它是記錄時間的。
# 如何使用
Stopwatch stopwatch = Stopwatch.createStarted();doSomething();stopwatch.stop();?long?millis?=?stopwatch.elapsed(MILLISECONDS);//?formatted?string?like?"12.3?ms"log.info("time: " + stopwatch);
安卓使用:
Stopwatch.createStarted(new Ticker() {public long read() {return android.os.SystemClock.elapsedRealtime();}});}
看了上面這段代碼,有人會說,不用 Stopwatch 照樣可以實(shí)現(xiàn)執(zhí)行時間的統(tǒng)計(jì),比如:
long?startTime?=?System.currentTimeMillis();try {// 模擬業(yè)務(wù)邏輯Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(System.currentTimeMillis() - startTime);
確實(shí)是,這樣也能統(tǒng)計(jì)這段代碼的執(zhí)行時間,那么為什么還會有 Stopwatch(我也有這種想法)
官方稱不直接使用System#nanoTime是有一下幾個原因:
時間源可以替代 可以重寫Ticker(下面會介紹)
nanoTime的返回值是納秒,返回的值沒有意義,Stopwatch抽象返回值
下面從實(shí)現(xiàn)方式來分析下guava為什么會設(shè)計(jì)這么類
# 源碼分析
內(nèi)部有幾個成員變量
//時間源 一般和Stopwatch一起使用,而不是單獨(dú)使用private final Ticker ticker;private boolean isRunning;private long elapsedNanos;private long startTick;
先看下Ticker(是個abstract類) 都有什么:
public static Ticker systemTicker() {return SYSTEM_TICKER;}private static final Ticker SYSTEM_TICKER =new Ticker() {public long read() {// 實(shí)際上就是System.nanoTime();return Platform.systemNanoTime();}};// 子類重寫???public?abstract?long?read();
回到Stopwatch,看下它的構(gòu)造方式:
public static Stopwatch createUnstarted() {return new Stopwatch();}/*** Creates (but does not start) a new stopwatch, using the specified time source.** @since 15.0*/public static Stopwatch createUnstarted(Ticker ticker) {return new Stopwatch(ticker);}/*** Creates (and starts) a new stopwatch using {@link System#nanoTime} as its time source.** @since 15.0*/public static Stopwatch createStarted() {return new Stopwatch().start();}Stopwatch() {this.ticker = Ticker.systemTicker();}Stopwatch(Ticker ticker) {this.ticker = checkNotNull(ticker, "ticker");}
包括創(chuàng)建不啟動,創(chuàng)建啟動的構(gòu)造方式
執(zhí)行流程
start--> stop 或者 reset
看下代碼,很簡單
public Stopwatch start() {// 先判斷是否處于執(zhí)行狀態(tài)checkState(!isRunning, "This stopwatch is already running.");isRunning = true;// 初始化 當(dāng)前的納秒時間startTick = ticker.read();return this;}public Stopwatch stop() {long tick = ticker.read();checkState(isRunning, "This stopwatch is already stopped.");isRunning = false;elapsedNanos += tick - startTick;return this;}public Stopwatch reset() {elapsedNanos = 0;isRunning = false;return this;??}
獲取結(jié)果的代碼:
// 計(jì)算納秒private long elapsedNanos() {return isRunning ? ticker.read() - startTick + elapsedNanos : elapsedNanos;}// 轉(zhuǎn)換其他單位public long elapsed(TimeUnit desiredUnit) {return desiredUnit.convert(elapsedNanos(), NANOSECONDS);}
還有一些單位轉(zhuǎn)換和toString方法,就不分析了。# 總結(jié)
支持TimeUnit,可以將計(jì)算后的時間轉(zhuǎn)換為各種單位 比如:stopwatch.elapsed(TimeUnit.SECONDS))
同一個Stopwatch,可以重置,重復(fù)記錄
時間源可以替代 可以重寫Ticker
其他 Spring 也有StopWatch 實(shí)現(xiàn)方式差不多,不支持替換時間源和可以重置,支持毫秒和納秒,但是增加了Task的概念
喜歡就三連呀
點(diǎn)擊"閱讀原文"可跳轉(zhuǎn)至我的博客。
關(guān)注 Stephen,一起學(xué)習(xí),一起成長。
