停表,很明显它是记录时间的"/>
Stopwatch 解释为计时器,又称秒表、停表,很明显它是记录时间的
# 如何使用
Stopwatch stopwatch = Stopwatch.createStarted();doSomething();stopwatch.stop(); // optionallong millis = stopwatch.elapsed(MILLISECONDS);
// formatted string like "12.3 ms"}log.info("time: " + stopwatch);
安卓使用:
Stopwatch.createStarted(new Ticker() {public long read() {return android.os.SystemClock.elapsedRealtime();}});}
看了上面这段代码,有人会说,不用Stopwatch 照样可以实现执行时间的统计,比如:
long startTime = System.currentTimeMillis();try {// 模拟业务逻辑Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(System.currentTimeMillis() - startTime);
确实是,这样也能统计这段代码的执行时间,那么为什么还会有Stopwatch(我也有这种想法)
官方称不直接使用System#nanoTime是有一下几个原因:
-
时间源可以替代 可以重写Ticker(下面会介绍)
-
nanoTime的返回值是纳秒,返回的值没有意义,Stopwatch抽象返回值
下面从实现方式来分析下guava为什么会设计这么类
# 源码分析
内部有几个成员变量
//时间源 一般和Stopwatch一起使用,而不是单独使用private final Ticker ticker;private boolean isRunning;private long elapsedNanos;private long startTick;
先看下Ticker(是个abstract类) 都有什么:
public static Ticker systemTicker() {return SYSTEM_TICKER;}private static final Ticker SYSTEM_TICKER =new Ticker() {@Overridepublic long read() {// 实际上就是System.nanoTime();return Platform.systemNanoTime();}};// 子类重写 public abstract long read();
回到Stopwatch,看下它的构造方式:
public static Stopwatch createUnstarted() {return new Stopwatch();}/*** Creates (but does not start) a new stopwatch, using the specified time source.** @since 15.0*/public static Stopwatch createUnstarted(Ticker ticker) {return new Stopwatch(ticker);}/*** Creates (and starts) a new stopwatch using {@link System#nanoTime} as its time source.** @since 15.0*/public static Stopwatch createStarted() {return new Stopwatch().start();}Stopwatch() {this.ticker = Ticker.systemTicker();}Stopwatch(Ticker ticker) {this.ticker = checkNotNull(ticker, "ticker");}
包括创建不启动,创建启动的构造方式
执行流程
start--> stop 或者 reset
看下代码,很简单
public Stopwatch start() {// 先判断是否处于执行状态checkState(!isRunning, "This stopwatch is already running.");isRunning = true;// 初始化 当前的纳秒时间startTick = ticker.read();return this;}public Stopwatch stop() {long tick = ticker.read();checkState(isRunning, "This stopwatch is already stopped.");isRunning = false;elapsedNanos += tick - startTick;return this;}public Stopwatch reset() {elapsedNanos = 0;isRunning = false;return this;}
获取结果的代码:
// 计算纳秒private long elapsedNanos() {return isRunning ? ticker.read() - startTick + elapsedNanos : elapsedNanos;}// 转换其他单位public long elapsed(TimeUnit desiredUnit) {return desiredUnit.convert(elapsedNanos(), NANOSECONDS);}
还有一些单位转换和toString方法,就不分析了
# 总结
-
支持TimeUnit,可以将计算后的时间转换为各种单位 比如:stopwatch.elapsed(TimeUnit.SECONDS))
-
同一个Stopwatch,可以重置,重复记录
-
时间源可以替代 可以重写Ticker
-
其他 Spring 也有StopWatch 实现方式差不多,不支持替换时间源和可以重置,支持毫秒和纳秒,但是增加了Task的概念
更多推荐
Stopwatch 解释为计时器,又称秒表、停表,很明显它是记录时间的
发布评论