番石榴的秒表是番石榴第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