Guava 中的 Stopwatch 是个什么鬼?
时间:2022-07-28
本文章向大家介绍Guava 中的 Stopwatch 是个什么鬼?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Stopwatch 解释为计时器,又称秒表、停表,很明显它是记录时间的。
# 如何使用
Stopwatch stopwatch = Stopwatch.createStarted();
doSomething();
stopwatch.stop(); // optional
long 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() {
@Override
public 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的概念
来源:https://my.oschina.net/lowkeysoft/blog/1595755
- Spring 数据库连接(Connection)绑定线程(Thread)的实现
- Golang语言实现AzDG可逆加密算法实例
- python django整理(五)配置favicon.ico,解决警告Not Found: /favicon.ico
- SpringMVC + Mybatis bug调试 SQL正确,查数据库却返回NULL
- 原生javascript实现图片轮播效果代码
- Spring AOP中 args和arg-names的区别
- Golong 语言开发 go-websocket-sample 测试值得拥有
- Java面试系列23-spring(2)-配置数据库驱动、依赖、Mapping等
- 【Golang语言社区】 Go语言中使用 Protobuf
- Java面试系列21-xml
- tensorflow载入数据的三种方式 之 TF生成数据的方法
- JS游戏开发 可移动地图的实现
- Java面试系列-多线程
- pymongo.errors:Sort operation used more than the maximum 33554432 bytes of RAM. Add an index,
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 你不知道的 MutationObserver
- 关于数组合并及对象去重的问题
- 关于弹窗广告—定时器、遮罩层
- macos-右键新建文件
- 使用node.js抓取其他网站数据,以及cheerio的介绍
- 使用mac上自带的apache,php
- 用孔子和老子的思想来分析忍者代码
- 省略号——中英文以及数字1旁边的差异
- 两有序数组间相加的TOPK问题
- 关于url传值的问题—encodeURIComponent
- Markdown 调整图片位置与大小
- 展开与折叠菜单动画
- Vue 中使用Pug
- curl在raw.githubusercontent.com下载文件时出现无法链接问题
- linux查看端口进程信息—lsof工具