Commons-lang3提供的StopWatch執行時間監視器, spring也提供了一樣功能的工具java
前言
咱們若是要統計一段代碼的執行時間:咱們的辦法是spring
public static void main(String[] args) { long startTime=System.currentTimeMillis(); //獲取開始時間 //函數主體代碼 //... long endTime=System.currentTimeMillis(); //獲取結束時間 System.out.println("程序運行時間: "+(endTime-startTime)+"ms"); }
假若咱們要展現成秒、甚至分鐘,還得咱們本身處理
可能到了JDK8之後,咱們變得稍微優雅一些了 能夠這麼處理:框架
Instant start = Instant.now(); //doSomething(); Instant end = Instant.now(); Duration duration = Duration.between(start, end); System.out.println("millis = " + duration.toMillis());
這個比上面優雅一點,靈活度也更強一些。但定義的變量有點多,整體上仍是不夠優雅。所以本文介紹StopWatch執行時間監視器,來統計咱們程序的執行時間,很是多的方便和優雅。函數
StopWatch:執行時間監視器
StopWatch有不少開源的框架都有提供相似的功能。好比Apache的commons-lang3,還有Spring framwork本身都有提供。工具
但本文只介紹lang3裏面的,功能上大同小異。並且Apache提供的功能強大,而且lang3包通常是咱們必導的包,但spring的就不必定了(好比純java項目,是不用導入spring包的),lang3的功用性也更強些。this
public static void main(String[] args) throws Exception { StopWatch watch = StopWatch.createStarted(); //建立後當即start,經常使用 //StopWatch watch = new StopWatch(); //watch.start(); Thread.sleep(1000); System.out.println("統計從開始到如今運行時間:" + watch.getTime() + "ms"); //1000ms Thread.sleep(1000); watch.split(); System.out.println("從start到此刻爲止的時間:" + watch.getTime()); System.out.println("從開始到第一個切入點運行時間:" + watch.getSplitTime()); //2245 Thread.sleep(1000); watch.split(); System.out.println("從開始到第二個切入點運行時間:" + watch.getSplitTime()); watch.reset(); //重置後必須使用start方法 watch.start(); Thread.sleep(1000); System.out.println("從新開始後到當前運行時間是:" + watch.getTime()); //1000 watch.suspend(); //暫停 Thread.sleep(6000); //模擬暫停6秒鐘 watch.resume(); //上面suspend,這裏要想從新統計,須要恢復一下 System.out.println("恢復後執行的時間是:" + watch.getTime()); //1000 注意此時這個值仍是1000 watch.stop(); System.out.println("花費的時間》》" + watch.getTime() + "ms"); //1002ms System.out.println("花費的時間》》" + watch.getTime(TimeUnit.SECONDS) + "s"); //1s 能夠直接轉成s }
如上就是StopWatch的基本使用方法。spa
getTime和getSplitTime有啥區別呢?
此處咱們看看getNanoTime()和getSplitNanoTime()便可pwa
public long getNanoTime() { if (this.runningState == State.STOPPED || this.runningState == State.SUSPENDED) { return this.stopTime - this.startTime; } else if (this.runningState == State.UNSTARTED) { return 0; } else if (this.runningState == State.RUNNING) { return System.nanoTime() - this.startTime; } throw new RuntimeException("Illegal running state has occurred."); } public long getSplitNanoTime() { if (this.splitState != SplitState.SPLIT) { throw new IllegalStateException("Stopwatch must be split to get the split time. "); } return this.stopTime - this.startTime; }
咱們發現:code
spilit()方法源碼以下:get
public void split() { if (this.runningState != State.RUNNING) { throw new IllegalStateException("Stopwatch is not running. "); } this.stopTime = System.nanoTime(); this.splitState = SplitState.SPLIT; }
咱們發現調用split方法後,watch的狀態改成了SPLIT。**且,且,且stopTime 設置爲了當前時間。**所以此處咱們的stopTime禁止了,這個時候調用getSplitNanoTime,用stopTime減去startTime便可。所以用此方法能夠插入先中止stopTime,最後再輸出。
而getTime()就是拿當前的時間戳,減去startTime,通常不涉及到stopTime的值,所以splitTime處理計算時間顯然更加的靈活,可是,通常咱們使用getTime()就足夠了
最後 不少時候,寫代碼也是一種藝術。但願咱們能有追求更加美好事物的心,這點對於接納新知識特別重要。所以此處推薦這個監視器來代替以前的的使用,能讓咱們更加靈活的控制程序代碼。