番石榴的秒表是番石榴第10版的另一個新番石榴類(作為Optional ,這是另一篇近期文章的主題)。 顧名思義,這個簡單的類提供了一種方便地測量兩個代碼點之間經過的時間的方法。 與使用System.currentTimeMillis()或System.nanoTime()相比,它具有多個優點。 在這里,我不關注這些優點,但是Stopwatch的Javadoc文檔確實涵蓋了其中一些優點。
正如Guava的許多類一樣, Stopwatch的獨特功能之一就是其簡單易用且命名正確。 該類具有兩個構造函數,一個不接受任何參數(可能是最常用的),另一個接受Ticker類的自定義擴展。 一旦獲得了Stopwatch
的實例,就可以使用具有“顯而易見”名稱的方法(例如start() , stop()和reset())來控制秒表,這很簡單。
任何給定的Stopwatch
實例都以累積方式記錄經過的時間。 換句話說,您可以多次啟動和停止秒表(只是不要啟動已經開始的秒表,也不要停止已經停止的秒表),并且經過的時間隨著每次啟動和停止而累積。 如果這不是所需要的,并且將使用秒表的單個實例來測量獨立事件(而不是并發事件),則在上一次運行的stop()
和下一次運行的start()
之間使用reset()
方法。 。
在使用番石榴的Stopwatch
時,我已經提到了一些注意事項。 首先,兩個連續start()
方法不應該對一個給定的實例調用Stopwatch
,而不首先與停止它stop()
進行第二次調用之前stop()
Stopwatch
具有一個實例方法isRunning() ,可用于在嘗試再次啟動秒表之前甚至在試圖停止已經停止或從未啟動過的秒表之前檢測正在運行的秒表。 大多數此類問題(例如兩次啟動秒表而不停止秒表或停止未運行或從未啟動的秒表)都會引發IllegalStateException 。 Guava開發人員利用自己的Preconditions類來確定這些異常條件并拋出這些異常。 Javadoc文檔中對此進行了進一步說明,即Stopwatch
不是線程安全的,應在單線程環境中使用。
到目前為止,所涵蓋的方法可處理構造Stopwatch
實例和管理秒表。 但是,只有在計時結果可供查看時,秒表幾乎總是有用的。 Stopwatch
類提供了兩種主要方法來訪問秒表實例記錄的經過時間。 一種方法elapsedMillis()類似于標準Java方法,該方法從時期開始返回毫秒。 此處的最大區別在于, Stopwatch
返回的是給定時間點stop()
調用start()
和stop()
)與絕對時間間隔以來經過的毫秒數。
我更喜歡elapsedTime(TimeUnit)來獲取秒表實例中記錄的經過時間。 該方法利用TimeUnit枚舉 (請參閱我在TimeUnit上的文章 )來指定經過時間的單位。這兩種用于報告經過時間的方法都可以在秒表運行時或停止后運行。
以下代碼清單包含一個類,該類演示了本文中突出顯示的Stopwatch方法。
StopWatchDemo.java
package dustin.examples;import static java.lang.System.out;import com.google.common.base.Stopwatch;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;/*** Demonstrates Guava's (Release 10) Stopwatch class.* * @author Dustin*/
public class StopWatchDemo
{private final static Logger LOGGER = Logger.getLogger(StopWatchDemo.class.getCanonicalName());public static void doSomethingJustToBeDoingIt(final int numberOfTimesToDoNothing){for (int count=0; count < numberOfTimesToDoNothing; count++){try{Thread.sleep(TimeUnit.SECONDS.toMillis(1));}catch (InterruptedException interruptEx){LOGGER.log(Level.INFO, 'Don't interrupt me when I'm trying to sleep!', interruptEx);}}}/*** Print statistics on Stopwatch-reported times for provided number of loops.* * @param numberLoops Number of loops executed.* @param stopwatch Stopwatch instance with time used statistics.*/public static void printElapsedTime(final int numberLoops, final Stopwatch stopwatch){if (stopwatch.isRunning()){out.println('WARNING! Your stopwatch is still running!');}else // stopwatch not running{out.println(numberLoops + ' loops required: ');out.println('\t' + stopwatch.toString(6));out.println('\t' + stopwatch.elapsedMillis() + ' elapsed milliseconds.');out.println('\t' + stopwatch.elapsedTime(TimeUnit.MINUTES) + ' minutes');out.println('\t' + stopwatch.elapsedTime(TimeUnit.SECONDS) + ' seconds');out.println('\t' + stopwatch.elapsedTime(TimeUnit.MILLISECONDS) + ' milliseconds');out.println('\t' + stopwatch.elapsedTime(TimeUnit.NANOSECONDS) + ' nanoseconds');}}public static void main(final String[] arguments){final Stopwatch stopwatch = new Stopwatch();int numberTimes = 5;stopwatch.start();doSomethingJustToBeDoingIt(numberTimes);stopwatch.stop();printElapsedTime(numberTimes, stopwatch);numberTimes = 45;stopwatch.reset();stopwatch.start();doSomethingJustToBeDoingIt(numberTimes);stopwatch.stop();printElapsedTime(numberTimes, stopwatch);numberTimes = 125;stopwatch.reset();stopwatch.start();doSomethingJustToBeDoingIt(numberTimes);stopwatch.stop();printElapsedTime(numberTimes, stopwatch);}
}
執行上述代碼后,其輸出與以下屏幕快照所示的輸出類似。
如果我注釋掉重置秒表實例的行,則秒表實例會累積經過的時間,而不是單獨跟蹤它。 下一個屏幕快照中顯示了這種差異。
Guava秒表類使執行簡單的計時測量變得容易,以分析某些操作需要多長時間。 它易于使用,并提供了靈活性,可輕松在所需時間范圍內提供輸出。
參考:來自JCG合作伙伴 Dustin Marx的Guava Stopwatch,來自Inspired by Actual Events博客。
翻譯自: https://www.javacodegeeks.com/2012/11/guava-stopwatch.html