最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2022年01月05日 10:43:48   作者:chx君  
這篇文章主要給大家介紹了關(guān)于Java計(jì)時(shí)新姿勢(shì)StopWatch的相關(guān)資料,以及java 中使用StopWatch來計(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í)間,都是以如下方式來進(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ì)輸出支持比較好。也就是說假如我們手里面有幾個(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)知,都是從使用開始,那就先來看看它的用法,會(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ī)矩,由淺入深??赐暧梅?,我們來看看源碼。先看下組成 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ù)鏈表
	 * 用來存儲(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;
    ...
}

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

方法說明
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ù)的計(jì)時(shí)。 傳入String類型的參數(shù)來開始指定任務(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í)常用的秒表的行為比較類似,我們先看一下其中的一些重要方法:

方法說明
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來計(jì)算時(shí)間差

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

eg:

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

我們可以使用已有的工具類中的秒表來替代上述的使用方式,現(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)視器來代替之前的的使用,能讓小伙伴們更加靈活的分析你的代碼~

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

相關(guān)文章

  • Java從入門到起飛之?dāng)?shù)組使用詳解

    Java從入門到起飛之?dāng)?shù)組使用詳解

    這篇文章主要介紹了Java從入門到起飛之?dāng)?shù)組使用的相關(guān)資料,包括數(shù)組的聲明、初始化、長(zhǎng)度、索引、遍歷和默認(rèn)值等內(nèi)容,還介紹了Arrays工具類中常用的方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-03-03
  • IDEA無法識(shí)別相關(guān)module模塊問題的解決過程

    IDEA無法識(shí)別相關(guān)module模塊問題的解決過程

    這篇文章主要給大家介紹了關(guān)于IDEA無法識(shí)別相關(guān)module模塊問題的解決過程,文中通過圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用IDEA具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • 淺析JAVA 循環(huán)結(jié)構(gòu)

    淺析JAVA 循環(huán)結(jié)構(gòu)

    這篇文章主要介紹了JAVA 循環(huán)結(jié)構(gòu)的相關(guān)資料,文中講解的非常細(xì)致,示例代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • Java通過socket客戶端保持連接服務(wù)端實(shí)現(xiàn)代碼

    Java通過socket客戶端保持連接服務(wù)端實(shí)現(xiàn)代碼

    這篇文章主要介紹了Java通過socket客戶端保持連接服務(wù)端實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 關(guān)于java中Map的九大問題分析

    關(guān)于java中Map的九大問題分析

    這篇文章主要為大家詳細(xì)分析了關(guān)于java中Map的九大問題,感興趣的小伙伴們可以參考一下
    2016-08-08
  • SpringBoot面試突擊之過濾器和攔截器區(qū)別詳解

    SpringBoot面試突擊之過濾器和攔截器區(qū)別詳解

    過濾器(Filter)和攔截器(Interceptor)都是基于?AOP(Aspect?Oriented?Programming,面向切面編程)思想實(shí)現(xiàn)的,用來解決項(xiàng)目中某一類問題的兩種“工具”,但二者有著明顯的差距,接下來我們一起來看
    2022-10-10
  • JS實(shí)現(xiàn)冒泡排序,插入排序和快速排序并排序輸出

    JS實(shí)現(xiàn)冒泡排序,插入排序和快速排序并排序輸出

    這篇文章主要介紹了JS實(shí)現(xiàn)冒泡排序,插入排序和快速排序并從input文本框中獲取內(nèi)容進(jìn)行排序輸出,需要的朋友可以參考下
    2015-07-07
  • springboot 動(dòng)態(tài)數(shù)據(jù)源的實(shí)現(xiàn)方法(Mybatis+Druid)

    springboot 動(dòng)態(tài)數(shù)據(jù)源的實(shí)現(xiàn)方法(Mybatis+Druid)

    這篇文章主要介紹了springboot 動(dòng)態(tài)數(shù)據(jù)源的實(shí)現(xiàn)方法(Mybatis+Druid),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • 關(guān)于java自定義線程池的原理與實(shí)現(xiàn)

    關(guān)于java自定義線程池的原理與實(shí)現(xiàn)

    本文介紹了如何自定義線程池和阻塞隊(duì)列,包括阻塞隊(duì)列的實(shí)現(xiàn)方法,線程池的構(gòu)建以及拒絕策略的應(yīng)用,詳細(xì)闡述了線程池中任務(wù)的提交和執(zhí)行流程,以及如何處理任務(wù)超出隊(duì)列容量的情況
    2022-04-04
  • Java8深入學(xué)習(xí)系列(二)函數(shù)式編程

    Java8深入學(xué)習(xí)系列(二)函數(shù)式編程

    函數(shù)式編程,這個(gè)詞語由兩個(gè)名詞構(gòu)成,函數(shù),編程。編程這個(gè)詞我就不用解釋了,大家都是做這個(gè)的。函數(shù),其實(shí)單獨(dú)抽離出來這個(gè)詞語,也并不陌生,那二者組合后的到底是什么呢,下面這篇文章主要給大家介紹了關(guān)于Java8函數(shù)式編程的相關(guān)資料,需要的朋友可以參考下。
    2017-08-08

最新評(píng)論

于田县| 共和县| 伊吾县| 土默特右旗| 富蕴县| 杭锦后旗| 清河县| 海南省| 桂阳县| 搜索| 正安县| 延川县| 滦南县| 新河县| 尼木县| 临沂市| 汨罗市| 富源县| 渝北区| 营山县| 白城市| 扶沟县| 遂平县| 北宁市| 宿州市| 葫芦岛市| 昌吉市| 南木林县| 日照市| 河源市| 诸城市| 阿合奇县| 商丘市| 岗巴县| 蒙城县| 绥阳县| 清水河县| 平阳县| 抚宁县| 嘉荫县| 蒙城县|