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() 方法,我们可以取消分割并继续计时。最后,我们停止计时器并输出总耗时。

posted @ 2024-11-04 17:44  哩个啷个波  阅读(13)  评论(0编辑  收藏  举报