计时器 StopWatch 类 - Google Guava

一、StopWatch 简介

StopWatch 用来计算经过的时间(精确到纳秒)

 

二、常用方法

官方文档:https://google.github.io/guava/releases/27.0.1-jre/api/docs/com/google/common/base/Stopwatch.html

方法类型方法描述
static Stopwatch

createStarted() 

创建启动一个新的stopwatch对象,用的是System.nanoTime()作为时间资源。

static Stopwatch

createStarted(Ticker ticker) 

创建启动一个新的stopwatch对象,用的是特定的时间资源。

static Stopwatch

createUnstarted() 

创建(但不启动)一个新的stopwatch对象,用的是System.nanoTime()作为时间资源。

static Stopwatch

createUnstarted(Ticker ticker) 

创建(但不启动)一个新的stopwatch对象,用的是特定的时间资源。

Duration

elapsed() 

返回将此秒表上显示的当前经过时间作为持续时间.

long

elapsed(TimeUnit desiredUnit) 

用特定的格式返回这个stopwatch经过的时间.

boolean

isRunning() 

如果start方法被调用。stop方法还没有调用。返回真.

Stopwatch

reset() 

把stopwatch经过的时间设置为零,状态设置为停止.

Stopwatch

start() 

启动 stopwatch.

Stopwatch

stop() 

停止stopwatch,读取的话将会返回经历过的时间.

String

toString() 

返回字符串形式的elapsed time.

// 创建stopwatch并开始计时
Stopwatch stopwatch = Stopwatch.createStarted();
Thread.sleep(1980);

// 以秒打印从计时开始至现在的所用时间,向下取整
System.out.println(stopwatch.elapsed(TimeUnit.SECONDS)); // 1

// 停止计时
stopwatch.stop();
System.out.println(stopwatch.elapsed(TimeUnit.SECONDS)); // 1

// 再次计时
stopwatch.start();
Thread.sleep(100);
System.out.println(stopwatch.elapsed(TimeUnit.SECONDS)); // 2

// 重置并开始
stopwatch.reset().start();
Thread.sleep(1030);

// 检查是否运行
System.out.println(stopwatch.isRunning()); // true
long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS); // 1034
System.out.println(millis);

// 打印
System.out.println(stopwatch.toString()); // 1.034 s

 

### Java 中 `System.currentTimeMillis()` 的不准原因 `System.currentTimeMillis()` 方法返回的是自1970年1月1日午夜(UTC时间)以来的毫秒数。然而,在某些情况下,它可能无法提供精确的结果。主要原因如下: #### 1. **依赖于操作系统时钟** 该方法基于操作系统的系统时钟,而系统时钟可能会受到多种因素的影响,例如手动调整、自动同步(NTP)、节能模式下的时钟漂移等[^2]。 #### 2. **分辨率较低** 在一些旧的操作系统或硬件上,`System.currentTimeMillis()` 的分辨率可能仅为几十毫秒甚至更高,这意味着两次调用之间的时间间隔小于其分辨率时,得到的结果可能是相同的[^1]。 --- ### 解决方案 为了获得更精确的时间测量,可以采用以下替代方案之一: #### 使用 `System.nanoTime()` 对于高精度的时间测量需求,推荐使用 `System.nanoTime()` 替代 `System.currentTimeMillis()`。`nanoTime()` 提供纳秒级的时间测量能力,并且不受系统时钟更改的影响。需要注意的是,`nanoTime()` 返回的值仅适用于计算时间差,而不表示实际的 wall-clock 时间。 以下是使用 `System.nanoTime()` 测量一段代码执行时间的示例: ```java long start = System.nanoTime(); // 执行某段代码 long end = System.nanoTime(); long duration = (end - start) / 1_000_000; // 将结果转换为毫秒 System.out.println("Code execution time: " + duration + " ms"); ``` #### 高精度计时器库 如果项目允许引入外部依赖,可以选择使用成熟的第三方库来处理时间测量问题。例如,Google Guava 库中的 `Stopwatch` 提供了简单易用的 API 来实现精准计时。 示例代码如下: ```java import com.google.common.base.Stopwatch; Stopwatch stopwatch = Stopwatch.createStarted(); // 执行某段代码 stopwatch.stop(); System.out.println("Elapsed time: " + stopwatch.elapsed().toMillis() + " ms"); ``` #### NTP 同步 当需要获取绝对时间戳并确保跨设备一致性时,可以通过网络时间协议(NTP)服务器校准时钟。Java 可以通过 HTTP 请求或其他方式连接到公共 NTP 服务器以获取标准时间。 --- ### Android 开发中的特殊场景 在 Android 平台中,由于设备多样性以及底层实现差异,单纯依靠 `System.currentTimeMillis()` 很难满足高性能应用的需求。特别是在涉及多线程并发、定时任务调度或者实时数据传输的情况下,建议优先选用 `System.nanoTime()` 或者其他专门设计的计时工具[^3]。 此外,针对分布式环境下的流量控制和服务限流等问题,除了客户端层面优化外,还需要结合服务端策略共同作用才能达到理想效果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值