spring-framework的StopWatch类详解,每个方法带有具体的例子

简介:

org.apache.commons.lang3.time.StopWatch 是 Apache Commons Lang 库中的一个工具类,用于测量代码执行时间。这个类提供了一系列便捷的方法,可以帮助我们轻松地对 Java 代码中的耗时操作进行计时。

StopWatch 类的应用场景:

StopWatch 类可以在许多场景下派上用场,例如:

  • 性能调优和基准测试:
    • 使用 StopWatch 可以方便地测量代码段的执行时间,从而找到可能存在性能问题的代码。
  • 运行时监控:
    • 在某些关键任务执行过程中,可以使用 StopWatch 记录其执行时间,以便在后期进行性能分析。
  • 操作计时:
    • 在需要精确计时的操作中,例如限制某个任务的执行时间,可以使用 StopWatch 进行计时。

StopWatch 类提供了以下一些主要方法:

start():

描述:启动计时器。如果计时器已经启动,则会抛出 IllegalStateException。

使用场景:开始测量代码段的执行时间。

源码:

public void start() {

if (this.runningState == State.STOPPED) {

throw new IllegalStateException("Stopwatch must be reset before being restarted. ");

}

if (this.runningState != State.UNSTARTED) {

throw new IllegalStateException("Stopwatch already started. ");

}

this.startTime = System.nanoTime();

this.startTimeMillis = System.currentTimeMillis();

this.runningState = State.RUNNING;

}

示例:

StopWatch stopWatch = new StopWatch();

stopWatch.start(); // 启动计时器

stop():

描述:停止计时器。如果计时器尚未启动,则会抛出 IllegalStateException。

使用场景:结束测量代码段的执行时间。

源码:

public void stop() {

if (this.runningState != State.RUNNING && this.runningState != State.SUSPENDED) {

throw new IllegalStateException("Stopwatch is not running. ");

}

if (this.runningState == State.RUNNING) {

this.stopTime = System.nanoTime();

}

this.runningState = State.STOPPED;

}

示例:

StopWatch stopWatch = new StopWatch();

stopWatch.start(); // 启动计时器

// ... 执行一段代码 ...

stopWatch.stop(); // 停止计时器

reset():

描述:重置计时器。将计时器状态恢复到初始状态。

使用场景:在连续测量多个代码段时,可以在每次测量之前重置计时器。

源码:

public void reset() {

this.runningState = State.UNSTARTED;

this.splitState = SplitState.UNSPLIT;

}

示例:

StopWatch stopWatch = new StopWatch();

stopWatch.start(); // 启动计时器

// ... 执行一段代码 ...

stopWatch.stop(); // 停止计时器

stopWatch.reset(); // 重置计时器

split():

描述:将计时器分割为两部分,此时可以获取分割点的时间。调用此方法后,计时器将继续运行。

使用场景:在测量一个长时间执行的任务时,可以使用此方法分割多个子任务的执行时间。

源码:

public void split() {

if (this.runningState != State.RUNNING) {

throw new IllegalStateException("Stopwatch is not running. ");

}

this.stopTime = System.nanoTime();

this.splitState = SplitState.SPLIT;

}

示例:

StopWatch stopWatch = new StopWatch();

stopWatch.start(); // 启动计时器

// ... 执行子任务1 ...

stopWatch.split(); // 分割计时器

// ... 执行子任务2 ...

stopWatch.stop(); // 停止计时器

unsplit():

描述:取消分割,恢复计时器到分割前的状态。

使用场景:在使用 split() 方法分割计时器后,如果需要恢复到分割前的状态,可以调用此方法。

源码:

public void unsplit() {

if (this.splitState != SplitState.SPLIT) {

throw new IllegalStateException("Stopwatch has not been split. ");

}

this.splitState = SplitState.UNSPLIT;

}

示例:

StopWatch stopWatch = new StopWatch();

stopWatch.start(); // 启动计时器

// ... 执行子任务1 ...

stopWatch.split(); // 分割计时器

// ... 执行子任务2 ...

stopWatch.unsplit(); // 取消分割

// ... 继续执行其他任务 ...

stopWatch.stop(); // 停止计时器

getTime():

描述:获取计时器记录的总时间,单位为毫秒。如果计时器正在运行,则返回当前已记录的时间;如果计时器已停止,则返回停止时的时间。

使用场景:在计时器停止后,获取代码段执行的总时间。

源码:

public long getTime() {

return getNanoTime() / NANO_2_MILLIS;

}

示例:

StopWatch stopWatch = new StopWatch();

stopWatch.start(); // 启动计时器

// ... 执行一段代码 ...

stopWatch.stop(); // 停止计时器

long elapsedTime = stopWatch.getTime(); // 获取已记录的时间

System.out.println("执行时间:" + elapsedTime + " 毫秒");

getStartTime():

描述:获取计时器开始时间,以毫秒为单位。返回值是自 epoch(1970-01-01T00:00:00Z)起的毫秒数。

使用场景:在需要获取计时器启动时的时间戳时使用。

源码:

public long getStartTime() {

if (this.runningState == State.UNSTARTED) {

throw new IllegalStateException("Stopwatch has not been started");

}

// System.nanoTime is for elapsed time

return this.startTimeMillis;

}

示例:

StopWatch stopWatch = new StopWatch();

stopWatch.start(); // 启动计时器

long startTime = stopWatch.getStartTime(); // 获取计时器启动时间

System.out.println("计时器启动时间:" + new Date(startTime));

toString():

描述:将计时器的状态以字符串形式返回。输出的格式为 "HH:mm:ss.SSS",表示经过的小时、分钟、秒和毫秒。

使用场景:当需要将计时器的状态以人类可读的形式输出时使用。

源码:

@Override

public String toString() {

final String msgStr = Objects.toString(message, StringUtils.EMPTY);

final String formattedTime = formatTime();

return msgStr.isEmpty() ? formattedTime : msgStr + StringUtils.SPACE + formattedTime;

}

示例:

StopWatch stopWatch = new StopWatch();

stopWatch.start(); // 启动计时器

// ... 执行一段代码 ...

stopWatch.stop(); // 停止计时器

System.out.println("执行时间:" + stopWatch.toString());

isStarted():

描述:检查计时器是否已启动。如果计时器已启动且尚未停止,则返回 true;否则返回 false。

使用场景:在需要检查计时器是否处于运行状态时使用。

源码:

public boolean isStarted() {

return runningState.isStarted();

}

示例:

StopWatch stopWatch = new StopWatch();

System.out.println("计时器是否已启动:" + stopWatch.isStarted()); // 输出:false

stopWatch.start(); // 启动计时器

System.out.println("计时器是否已启动:" + stopWatch.isStarted()); // 输出:true

isStopped():

描述:检查计时器是否已停止。如果计时器已停止,则返回 true;否则返回 false。

使用场景:在需要检查计时器是否处于停止状态时使用。

源码:

public boolean isStopped() {

return runningState.isStopped();

}

示例:

StopWatch stopWatch = new StopWatch();

System.out.println("计时器是否已停止:" + stopWatch.isStopped()); // 输出:true

stopWatch.start(); // 启动计时器

System.out.println("计时器是否已停止:" + stopWatch.isStopped()); // 输出:false

stopWatch.stop(); // 停止计时器

System.out.println("计时器是否已停止:" + stopWatch.isStopped()); // 输出:true

示例代码:

以下是一个使用 StopWatch 测量代码执行时间的简单示例:

import org.apache.commons.lang3.time.StopWatch;



public class StopWatchExample {

    public static void main(String[] args) throws InterruptedException {

        // 创建一个 StopWatch 实例

        StopWatch stopWatch = new StopWatch();



        // 启动计时器

        stopWatch.start();



        // 执行一段耗时操作

        Thread.sleep(2000);



        // 停止计时器

        stopWatch.stop();



        // 输出执行时间

        System.out.println("耗时:" + stopWatch.getTime() + " 毫秒");

    }

}

在这个示例中,我们创建了一个 StopWatch 实例,然后使用 start() 方法开始计时。接下来,我们执行一个简单的耗时操作(暂停线程 2 秒),最后使用 stop() 方法停止计时器。最后,我们输出耗时,可以看到结果大约是 2000 毫秒。

以下是一个使用 StopWatch 类的复杂示例,该示例演示了如何使用 split() 和 unsplit() 方法来分割和取消分割计时器,以及如何使用 getTime() 方法获取分割点的时间:

import org.apache.commons.lang3.time.StopWatch;



public class ComplexStopWatchExample {

    public static void main(String[] args) throws InterruptedException {

        StopWatch stopWatch = new StopWatch();

        stopWatch.start(); // 启动计时器



        // 执行子任务1,耗时1000毫秒

        Thread.sleep(1000);

        stopWatch.split(); // 分割计时器

        System.out.println("子任务1耗时:" + stopWatch.getTime() + " 毫秒");



        // 执行子任务2,耗时2000毫秒

        Thread.sleep(2000);

        stopWatch.split(); // 分割计时器

        System.out.println("子任务2耗时:" + (stopWatch.getTime() - stopWatch.getSplitTime()) + " 毫秒");



        // 取消分割,继续执行其他任务

        stopWatch.unsplit();

        // 执行子任务3,耗时1500毫秒

        Thread.sleep(1500);

        stopWatch.stop(); // 停止计时器

        System.out.println("总耗时:" + stopWatch.getTime() + " 毫秒");

    }

}

在这个示例中,我们执行了三个子任务,并使用 split() 方法在每个子任务之间进行分割。通过调用 getTime() 方法并减去之前的分割时间,我们可以得到每个子任务的执行时间。通过调用 unsplit() 方法,我们可以取消分割并继续计时。最后,我们停止计时器并输出总耗时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加油当当

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值