前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Guava 中的 Stopwatch 是个什么鬼?

Guava 中的 Stopwatch 是个什么鬼?

作者头像
程序猿DD
发布2020-10-27 16:44:27
1.3K0
发布2020-10-27 16:44:27
举报
文章被收录于专栏:程序猿DD

Stopwatch 解释为计时器,又称秒表、停表,很明显它是记录时间的。

# 如何使用

代码语言:javascript
复制
Stopwatch stopwatch = Stopwatch.createStarted();
   doSomething();
 stopwatch.stop(); // optional

   long millis = stopwatch.elapsed(MILLISECONDS);
// formatted string like "12.3 ms"}

log.info("time: " + stopwatch);
代码语言:javascript
复制

安卓使用:

代码语言:javascript
复制
Stopwatch.createStarted(
         new Ticker() {
           public long read() {
             return android.os.SystemClock.elapsedRealtime();
            }
          });}
代码语言:javascript
复制

看了上面这段代码,有人会说,不用Stopwatch 照样可以实现执行时间的统计,比如:

代码语言:javascript
复制
   long startTime = System.currentTimeMillis();

        try {
            // 模拟业务逻辑
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(System.currentTimeMillis() - startTime);
代码语言:javascript
复制

确实是,这样也能统计这段代码的执行时间,那么为什么还会有Stopwatch(我也有这种想法)

官方称不直接使用System#nanoTime是有一下几个原因:

  • 时间源可以替代 可以重写Ticker(下面会介绍)
  • nanoTime的返回值是纳秒,返回的值没有意义,Stopwatch抽象返回值

下面从实现方式来分析下guava为什么会设计这么类

# 源码分析

内部有几个成员变量

代码语言:javascript
复制
  //时间源 一般和Stopwatch一起使用,而不是单独使用
  private final Ticker ticker;
  private boolean isRunning;
  private long elapsedNanos;
  private long startTick;
代码语言:javascript
复制
先看下Ticker(是个abstract类) 都有什么:
代码语言:javascript
复制
  public static Ticker systemTicker() {
    return SYSTEM_TICKER;
  }

  private static final Ticker SYSTEM_TICKER =
      new Ticker() {
        @Override
        public long read() {
          // 实际上就是System.nanoTime();
          return Platform.systemNanoTime();
        }
      };
   
   // 子类重写   
   public abstract long read();
代码语言:javascript
复制

回到Stopwatch,看下它的构造方式:

代码语言:javascript
复制
  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");
  }
代码语言:javascript
复制

包括创建不启动,创建启动的构造方式

执行流程

start--> stop 或者 reset

看下代码,很简单

代码语言:javascript
复制
 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;
  }
代码语言:javascript
复制

获取结果的代码:

代码语言:javascript
复制
  // 计算纳秒
  private long elapsedNanos() {
    return isRunning ? ticker.read() - startTick + elapsedNanos : elapsedNanos;
  }

  // 转换其他单位
  public long elapsed(TimeUnit desiredUnit) {
    return desiredUnit.convert(elapsedNanos(), NANOSECONDS);
  }
代码语言:javascript
复制
还有一些单位转换和toString方法,就不分析了

# 总结

  • 支持TimeUnit,可以将计算后的时间转换为各种单位 比如:stopwatch.elapsed(TimeUnit.SECONDS))
  • 同一个Stopwatch,可以重置,重复记录
  • 时间源可以替代 可以重写Ticker
  • 其他 Spring 也有StopWatch 实现方式差不多,不支持替换时间源和可以重置,支持毫秒和纳秒,但是增加了Task的概念

来源:https://my.oschina.net/lowkeysoft/blog/1595755

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序猿DD 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 如何使用
  • # 源码分析
    • 内部有几个成员变量
      • 先看下Ticker(是个abstract类) 都有什么:
    • 回到Stopwatch,看下它的构造方式:
      • 执行流程
        • 获取结果的代码:
        • # 总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档