Java開發(fā)利器Commons Lang之計時器StopWatch

標準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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市贞瞒,隨后出現的幾起案子,更是在濱河造成了極大的恐慌军浆,老刑警劉巖乒融,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異赞季,居然都是意外死亡,警方通過查閱死者的電腦和手機次绘,發(fā)現死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門撒遣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人禾进,你說我怎么就攤上這事廉涕。” “怎么了壶愤?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵馏鹤,是天一觀的道長。 經常有香客問我湃累,道長碍讨,這世上最難降的妖魔是什么蒙秒? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任晕讲,我火速辦了婚禮,結果婚禮上瓢省,老公的妹妹穿的比我還像新娘。我一直安慰自己摹量,他們只是感情好馒胆,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著睦尽,像睡著了一般型雳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上四啰,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天柑晒,我揣著相機與錄音眷射,去河邊找鬼。 笑死妖碉,一個胖子當著我的面吹牛,可吹牛的內容都是我干的欧宜。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼匹中,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了顶捷?” 一聲冷哼從身側響起屎篱,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤交播,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后堪侯,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡芽死,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年次洼,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揖曾。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡亥啦,死狀恐怖,靈堂內的尸體忽然破棺而出奴拦,到底是詐尸還是另有隱情届吁,我是刑警寧澤,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布暂氯,位于F島的核電站亮蛔,受9級特大地震影響痴施,放射性物質發(fā)生泄漏。R本人自食惡果不足惜晾剖,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望齿尽。 院中可真熱鬧,春花似錦绵估、人聲如沸卡骂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浓若。三九已至渺杉,卻和暖如春挪钓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背倚评。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工馏予, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人霞丧。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓呢岗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蚯妇。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361