欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java計(jì)時(shí)新姿勢(shì)StopWatch的使用方法詳解

 更新時(shí)間:2022年01月05日 10:43:48   作者:chx君  
這篇文章主要給大家介紹了關(guān)于Java計(jì)時(shí)新姿勢(shì)StopWatch的相關(guān)資料,以及java 中使用StopWatch來(lái)計(jì)算時(shí)間差的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

一、背景

有時(shí)我們?cè)谧鲩_發(fā)的時(shí)候需要記錄每個(gè)任務(wù)執(zhí)行時(shí)間,或者記錄一段代碼執(zhí)行時(shí)間,最簡(jiǎn)單的方法就是打印當(dāng)前時(shí)間與執(zhí)行完時(shí)間的差值,一般我們檢測(cè)某段代碼執(zhí)行的時(shí)間,都是以如下方式來(lái)進(jìn)行的:

public static void main(String[] args) {
  Long startTime = System.currentTimeMillis();
  // 你的業(yè)務(wù)代碼
  Long endTime = System.currentTimeMillis();
  Long elapsedTime = (endTime - startTime) / 1000;
  System.out.println("該段總共耗時(shí):" + elapsedTime + "s");
}

事實(shí)上該方法通過獲取執(zhí)行完成時(shí)間與執(zhí)行開始時(shí)間的差值得到程序的執(zhí)行時(shí)間,簡(jiǎn)單直接有效,但想必寫多了也是比較煩人的,尤其是碰到不可描述的代碼時(shí),會(huì)更加的讓人忍不住多寫幾個(gè)bug聊表敬意,而且如果想對(duì)執(zhí)行的時(shí)間做進(jìn)一步控制,則需要在程序中很多地方修改。此時(shí)會(huì)想是否有一個(gè)工具類,提供了這些方法,剛好可以滿足這種場(chǎng)景?我們可以利用已有的工具類中的秒表,常見的秒表工具類有 org.springframework.util.StopWatch、org.apache.commons.lang.time.StopWatch以及谷歌提供的guava中的秒表(這個(gè)我沒怎么用過)。這里重點(diǎn)講下基于spring、Apache的使用

二、spring 用法

2.1 初遇

StopWatch 是位于 org.springframework.util 包下的一個(gè)工具類,通過它可方便的對(duì)程序部分代碼進(jìn)行計(jì)時(shí)(ms級(jí)別),適用于同步單線程代碼塊。簡(jiǎn)單總結(jié)一句,Spring提供的計(jì)時(shí)器StopWatch對(duì)于秒、毫秒為單位方便計(jì)時(shí)的程序,尤其是單線程、順序執(zhí)行程序的時(shí)間特性的統(tǒng)計(jì)輸出支持比較好。也就是說(shuō)假如我們手里面有幾個(gè)在順序上前后執(zhí)行的幾個(gè)任務(wù),而且我們比較關(guān)心幾個(gè)任務(wù)分別執(zhí)行的時(shí)間占用狀況,希望能夠形成一個(gè)不太復(fù)雜的日志輸出,StopWatch提供了這樣的功能。而且Spring的StopWatch基本上也就是僅僅為了這樣的功能而實(shí)現(xiàn)。

想要使用它,首先你需要在你的 Maven 中引入 Spring 核心包,當(dāng)然 Spring MVC 和 Spring Boot 都已經(jīng)自動(dòng)引入了該包:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>

對(duì)一切事物的認(rèn)知,都是從使用開始,那就先來(lái)看看它的用法,會(huì)如下所示:

public static void main(String[] args) throws InterruptedException {
    StopWatch stopWatch = new StopWatch();

    // 任務(wù)一模擬休眠3秒鐘
    stopWatch.start("TaskOneName");
    Thread.sleep(1000 * 3);
    System.out.println("當(dāng)前任務(wù)名稱:" + stopWatch.currentTaskName());
    stopWatch.stop();

    // 任務(wù)一模擬休眠10秒鐘
    stopWatch.start("TaskTwoName");
    Thread.sleep(1000 * 10);
    System.out.println("當(dāng)前任務(wù)名稱:" + stopWatch.currentTaskName());
    stopWatch.stop();

    // 任務(wù)一模擬休眠10秒鐘
    stopWatch.start("TaskThreeName");
    Thread.sleep(1000 * 10);
    System.out.println("當(dāng)前任務(wù)名稱:" + stopWatch.currentTaskName());
    stopWatch.stop();

    // 打印出耗時(shí)
    System.out.println(stopWatch.prettyPrint());
    System.out.println(stopWatch.shortSummary());
    // stop后它的值為null
    System.out.println(stopWatch.currentTaskName()); 
    
    // 最后一個(gè)任務(wù)的相關(guān)信息
    System.out.println(stopWatch.getLastTaskName());
    System.out.println(stopWatch.getLastTaskInfo());
    
    // 任務(wù)總的耗時(shí)  如果你想獲取到每個(gè)任務(wù)詳情(包括它的任務(wù)名、耗時(shí)等等)可使用
    System.out.println("所有任務(wù)總耗時(shí):" + sw.getTotalTimeMillis());
    System.out.println("任務(wù)總數(shù):" + sw.getTaskCount());
    System.out.println("所有任務(wù)詳情:" + sw.getTaskInfo());
}

如圖所示,StopWatch 不僅正確記錄了上個(gè)任務(wù)的執(zhí)行時(shí)間,并且在最后還可以給出精確的任務(wù)執(zhí)行時(shí)間(納秒級(jí)別)和耗時(shí)占比,這或許就會(huì)比我們自己輸出要優(yōu)雅那么一些。

2.2 源碼

老規(guī)矩,由淺入深??赐暧梅?,我們來(lái)看看源碼。先看下組成 StopWatch 的屬性

public class StopWatch {
    /**
	 * 本實(shí)例的唯一 Id,用于在日志或控制臺(tái)輸出時(shí)區(qū)分的。
	 */
    private final String id;
    /**
	 * 是否保持一個(gè) taskList 鏈表
	 * 每次停止計(jì)時(shí)時(shí),會(huì)將當(dāng)前任務(wù)放入這個(gè)鏈表,用以記錄任務(wù)鏈路和計(jì)時(shí)分析
	 */
	private boolean keepTaskList = true;
   /**
	 * 任務(wù)鏈表
	 * 用來(lái)存儲(chǔ)每個(gè)task的信息, taskInfo由taskName 和 totoalTime組成
	 */
    private final List<StopWatch.TaskInfo> taskList;
    /**
	 * 當(dāng)前任務(wù)的開始時(shí)間
	 */
    private long startTimeMillis;
    /**
	 * 
	 */
    private boolean running;
    /**
	 * 當(dāng)前任務(wù)名稱
	 */
    private String currentTaskName;
    /**
	 * 最后一個(gè)任務(wù)的信息
	 */
    private StopWatch.TaskInfo lastTaskInfo;
    /**
	 * 任務(wù)總數(shù)
	 */
    private int taskCount;
    /**
	 * 程序執(zhí)行時(shí)間
	 */
    private long totalTimeMillis;
    ...
}

接下來(lái),我們看一下StopWatch類的構(gòu)造器和一些關(guān)鍵方法

方法說(shuō)明
new StopWatch()構(gòu)建一個(gè)新的秒表,不開始任何任務(wù)。
new StopWatch(String id)創(chuàng)建一個(gè)指定了id的StopWatch
String getId()返回此秒表的ID
void start(String taskName)不傳入?yún)?shù),開始一個(gè)無(wú)名稱的任務(wù)的計(jì)時(shí)。 傳入String類型的參數(shù)來(lái)開始指定任務(wù)名的任務(wù)計(jì)時(shí)
void stop()停止當(dāng)前任務(wù)的計(jì)時(shí)
boolean isRunning()是否正在計(jì)時(shí)某任務(wù)
String currentTaskName()當(dāng)前正在運(yùn)行的任務(wù)的名稱(如果有)
long getTotalTimeMillis()所有任務(wù)的總體執(zhí)行時(shí)間(毫秒單位)
double getTotalTimeSeconds()所有任務(wù)的總時(shí)間(以秒為單位)
String getLastTaskName()上一個(gè)任務(wù)的名稱
long getLastTaskTimeMillis()上一個(gè)任務(wù)的耗時(shí)(毫秒單位)
int getTaskCount()定時(shí)任務(wù)的數(shù)量
String shortSummary()總運(yùn)行時(shí)間的簡(jiǎn)短描述
String prettyPrint()優(yōu)美地打印所有任務(wù)的詳細(xì)耗時(shí)情況

2.3 注意事項(xiàng)

  • StopWatch對(duì)象不是設(shè)計(jì)為線程安全的,并且不使用同步。
  • 一個(gè)StopWatch實(shí)例一次只能開啟一個(gè)task,不能同時(shí)start多個(gè)task
  • 在該task還沒stop之前不能start一個(gè)新的task,必須在該task stop之后才能開啟新的task
  • 若要一次開啟多個(gè),需要new不同的StopWatch實(shí)例

三、apache 用法

StopWath是 apache commons lang3 包下的一個(gè)任務(wù)執(zhí)行時(shí)間監(jiān)視器,與我們平時(shí)常用的秒表的行為比較類似,我們先看一下其中的一些重要方法:

方法說(shuō)明
new StopWatch()構(gòu)建一個(gè)新的秒表,不開始任何任務(wù)。
static StopWatch createStarted() 
void start()開始計(jì)時(shí)
void stop()停止當(dāng)前任務(wù)的計(jì)時(shí)
void reset()重置計(jì)時(shí)
void split()設(shè)置split點(diǎn)
void unsplit() 
void suspend()暫停計(jì)時(shí), 直到調(diào)用resume()后才恢復(fù)計(jì)時(shí)
void resume()恢復(fù)計(jì)時(shí)
long getTime()統(tǒng)計(jì)從start到現(xiàn)在的計(jì)時(shí)
long getTime(final TimeUnit timeUnit) 
long getNanoTime() 
long getSplitTime()獲取從start 到 最后一次split的時(shí)間
long getSplitNanoTime() 
long getStartTime() 
boolean isStarted() 
boolean isSuspended() 
boolean isStopped() 
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.6</version>
</dependency>

Apache提供的這個(gè)任務(wù)執(zhí)行監(jiān)視器功能豐富強(qiáng)大,靈活性強(qiáng),如下經(jīng)典實(shí)用案例:

public static void main(String[] args) throws InterruptedException {
    //創(chuàng)建后立即start,常用
    StopWatch watch = StopWatch.createStarted();

    // StopWatch watch = new StopWatch();
    // watch.start();

    Thread.sleep(1000);
    System.out.println(watch.getTime());
    System.out.println("統(tǒng)計(jì)從開始到現(xiàn)在運(yùn)行時(shí)間:" + watch.getTime() + "ms");

    Thread.sleep(1000);
    watch.split();
    System.out.println("從start到此刻為止的時(shí)間:" + watch.getTime());
    System.out.println("從開始到第一個(gè)切入點(diǎn)運(yùn)行時(shí)間:" + watch.getSplitTime());


    Thread.sleep(1000);
    watch.split();
    System.out.println("從開始到第二個(gè)切入點(diǎn)運(yùn)行時(shí)間:" + watch.getSplitTime());

    // 復(fù)位后, 重新計(jì)時(shí)
    watch.reset();
    watch.start();
    Thread.sleep(1000);
    System.out.println("重新開始后到當(dāng)前運(yùn)行時(shí)間是:" + watch.getTime());

    // 暫停 與 恢復(fù)
    watch.suspend();
    System.out.println("暫停2秒鐘");
    Thread.sleep(2000);

    // 上面suspend,這里要想重新統(tǒng)計(jì),需要恢復(fù)一下
    watch.resume();
    System.out.println("恢復(fù)后執(zhí)行的時(shí)間是:" + watch.getTime());

    Thread.sleep(1000);
    watch.stop();

    System.out.println("花費(fèi)的時(shí)間》》" + watch.getTime() + "ms");
    // 直接轉(zhuǎn)成s
    System.out.println("花費(fèi)的時(shí)間》》" + watch.getTime(TimeUnit.SECONDS) + "s");
}

四、java 中使用StopWatch來(lái)計(jì)算時(shí)間差

以前在進(jìn)行時(shí)間耗時(shí)時(shí)我們通常的做法是先給出計(jì)算前后兩個(gè)的時(shí)間值,然后通過詳見來(lái)計(jì)算耗時(shí)時(shí)長(zhǎng)。

eg:

long start = System.currentTimeMillis();      
......業(yè)務(wù)處理
System.out.println("耗時(shí):" + (System.currentTimeMillis() - start) + "ms");

我們可以使用已有的工具類中的秒表來(lái)替代上述的使用方式,現(xiàn)有的秒表工具類有org.springframework.util.StopWatch、org.apache.commons.lang.time.StopWatch,這里以Spring的StopWatch類為例:

public static void main(String[] args) throws InterruptedException{

        StopWatch stopWatch = new StopWatch("任務(wù)耗時(shí)秒表工具");

        stopWatch.start("task1");
        Thread.sleep(1000);
        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis());
        stopWatch.start("task2");
        Thread.sleep(3000);
        stopWatch.stop();
        //所有任務(wù)耗時(shí)時(shí)間
        System.out.println(stopWatch.getTotalTimeMillis());
        System.out.println(stopWatch.prettyPrint());

        StopWatch stopWatch2 = new StopWatch("任務(wù)耗時(shí)秒表工具2");
        stopWatch2.start("task3");
        Thread.sleep(3000);
        stopWatch2.stop();
        //所有任務(wù)耗時(shí)時(shí)間
        System.out.println(stopWatch2.getTotalTimeMillis());
        System.out.println(stopWatch2.prettyPrint());

    }

 

五、最后

很多時(shí)候,寫代碼也是一種藝術(shù),而借助這種實(shí)用工具我就覺得藝術(shù)感更強(qiáng)些。希望我們能有追求更加美好事物的心,這點(diǎn)對(duì)于接納新知識(shí)特別重要。此處推薦這個(gè)監(jiān)視器來(lái)代替之前的的使用,能讓小伙伴們更加靈活的分析你的代碼~

到此這篇關(guān)于Java計(jì)時(shí)新姿勢(shì)StopWatch使用的文章就介紹到這了,更多相關(guān)Java計(jì)時(shí)StopWatch內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Springboot對(duì)多線程的支持

    詳解Springboot對(duì)多線程的支持

    Spring是通過任務(wù)執(zhí)行器(TaskExecutor)來(lái)實(shí)現(xiàn)多線程和并發(fā)編程,使用ThreadPoolTaskExecutor來(lái)創(chuàng)建一個(gè)基于線城池的TaskExecutor。這篇文章給大家介紹Springboot對(duì)多線程的支持,感興趣的朋友一起看看吧
    2018-07-07
  • 關(guān)于Mybatis中foreach遍歷Map的實(shí)現(xiàn)示例

    關(guān)于Mybatis中foreach遍歷Map的實(shí)現(xiàn)示例

    這篇文章主要介紹了關(guān)于Mybatis中foreach遍歷Map的實(shí)現(xiàn)示例,MyBatis?是一款優(yōu)秀的半自動(dòng)的ORM持久層框架,它支持自定義?SQL、存儲(chǔ)過程以及高級(jí)映射,需要的朋友可以參考下
    2023-05-05
  • springboot整合freemarker代碼自動(dòng)生成器

    springboot整合freemarker代碼自動(dòng)生成器

    最近做了一個(gè)工具,可以實(shí)現(xiàn)代碼自動(dòng)生成,今天整理出來(lái)分享給大家,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 淺談Spring 的Controller 是單例or多例

    淺談Spring 的Controller 是單例or多例

    這篇文章主要介紹了淺談Spring 的Controller 是單例or多例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • SpringMVC注解的入門實(shí)例詳解

    SpringMVC注解的入門實(shí)例詳解

    這篇文章主要為大家介紹了SpringMVC注解的入門實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • SpringBoot2 整合 ClickHouse數(shù)據(jù)庫(kù)案例解析

    SpringBoot2 整合 ClickHouse數(shù)據(jù)庫(kù)案例解析

    這篇文章主要介紹了SpringBoot2 整合 ClickHouse數(shù)據(jù)庫(kù)案例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • java DateUtil工具類時(shí)間戳類型轉(zhuǎn)換詳解

    java DateUtil工具類時(shí)間戳類型轉(zhuǎn)換詳解

    這篇文章主要為大家詳細(xì)介紹了java DateUtil工具類時(shí)間戳類型轉(zhuǎn)換的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • springboot打包jar中沒有主清單屬性問題

    springboot打包jar中沒有主清單屬性問題

    這篇文章主要介紹了springboot打包jar中沒有主清單屬性問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java實(shí)現(xiàn)簡(jiǎn)單撲克牌游戲

    java實(shí)現(xiàn)簡(jiǎn)單撲克牌游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單撲克牌游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • 如何在Intellij中安裝LeetCode刷題插件方便Java刷題

    如何在Intellij中安裝LeetCode刷題插件方便Java刷題

    這篇文章主要介紹了如何在Intellij中安裝LeetCode刷題插件方便Java刷題,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08

最新評(píng)論