Spring 工具类StopWatch(统计耗时)

烟雨 3年前 (2022-09-01) 阅读数 590 #Spring
文章标签 Spring

StopWatch 是位于 org.springframework.util 包下的一个工具类,通过它可方便的对程序部分代码进行计时(ms级别),适用于同步单线程代码块。简单总结一句,Spring提供的计时器StopWatch对于秒、毫秒为单位方便计时的程序,尤其是单线程、顺序执行程序的时间特性的统计输出支持比较好。也就是说假如我们手里面有几个在顺序上前后执行的几个任务,而且我们比较关心几个任务分别执行的时间占用状况,希望能够形成一个不太复杂的日志输出,StopWatch提供了这样的功能。而且Spring的StopWatch基本上也就是仅仅为了这样的功能而实现。

想要使用它,首先你需要在你的 Maven 中引入 Spring 核心包,当然 Spring MVC 和 Spring Boot 都已经自动引入了该包:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>

入门案例

public static void main(String[] args) throws InterruptedException {
    StopWatch stopWatch = new StopWatch();

    // 任务一模拟休眠3秒钟
    stopWatch.start("TaskOneName");
    Thread.sleep(1000 * 3);
    System.out.println("当前任务名称:" + stopWatch.currentTaskName());
    stopWatch.stop();
    System.out.println("上一个任务执行时间:" + stopWatch.getLastTaskTimeMillis() + "(ms)");

    // 任务一模拟休眠10秒钟
    stopWatch.start("TaskTwoName");
    Thread.sleep(1000 * 10);
    System.out.println("当前任务名称:" + stopWatch.currentTaskName());
    stopWatch.stop();
    System.out.println("上一个任务执行时间:" + stopWatch.getLastTaskTimeMillis() + "(ms)");

    // 任务一模拟休眠10秒钟
    stopWatch.start("TaskThreeName");
    Thread.sleep(1000 * 10);
    System.out.println("当前任务名称:" + stopWatch.currentTaskName());
    stopWatch.stop();
    System.out.println("上一个任务执行时间:" + stopWatch.getLastTaskTimeMillis() + "(ms)");


    // 打印出耗时
    System.out.println();
    System.out.println(stopWatch.prettyPrint());

    System.out.println();
    System.out.println(stopWatch.shortSummary());
    // stop后它的值为null
    System.out.println(stopWatch.currentTaskName());

    // 最后一个任务的相关信息
    System.out.println(stopWatch.getLastTaskName());
    System.out.println(stopWatch.getLastTaskInfo());

    // 任务总的耗时 如果你想获取到每个任务详情(包括它的任务名、耗时等等)可使用
    System.out.println("所有任务总耗时:" + stopWatch.getTotalTimeMillis() + "(ms)");
    System.out.println("任务总数:" + stopWatch.getTaskCount());
    System.out.println("所有任务详情列表:" + Arrays.toString(stopWatch.getTaskInfo()));
}

执行结果

当前任务名称:TaskOneName
上一个任务执行时间:3000(ms)
当前任务名称:TaskTwoName
上一个任务执行时间:10002(ms)
当前任务名称:TaskThreeName
上一个任务执行时间:10012(ms)

StopWatch '': running time = 23015695000 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
3000843900  013%  TaskOneName
10002746900  043%  TaskTwoName
10012104200  044%  TaskThreeName


StopWatch '': running time = 23015695000 ns
null
TaskThreeName
org.springframework.util.StopWatch$TaskInfo@4517d9a3
所有任务总耗时:23015(ms)
任务总数:3
所有任务详情列表:[org.springframework.util.StopWatch$TaskInfo@372f7a8d, org.springframework.util.StopWatch$TaskInfo@2f92e0f4, org.springframework.util.StopWatch$TaskInfo@4517d9a3]

源码

public class StopWatch {
    /**
   * 本实例的唯一 Id,用于在日志或控制台输出时区分的。
   */
    private final String id;
    /**
   * 是否保持一个 taskList 链表
   * 每次停止计时时,会将当前任务放入这个链表,用以记录任务链路和计时分析
   */
  private boolean keepTaskList = true;
   /**
   * 任务链表
   * 用来存储每个task的信息, taskInfo由taskName 和 totoalTime组成
   */
    private final List<StopWatch.TaskInfo> taskList;
    /**
   * 当前任务的开始时间
   */
    private long startTimeMillis;
    /**
   *
   */
    private boolean running;
    /**
   * 当前任务名称
   */
    private String currentTaskName;
    /**
   * 最后一个任务的信息
   */
    private StopWatch.TaskInfo lastTaskInfo;
    /**
   * 任务总数
   */
    private int taskCount;
    /**
   * 程序执行时间
   */
    private long totalTimeMillis;
    ...
}

image.png

用法注意
  • StopWatch对象不是设计为线程安全的,并且不使用同步。

  • 一个StopWatch实例一次只能开启一个task,不能同时start多个task。

  • 在该task还没stop之前不能start一个新的task,必须在该task stop之后才能开启新的task。

  • 若要一次开启多个,需要new不同的StopWatch实例。


版权声明

非特殊说明,本文由Zender原创或收集发布,欢迎转载。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

作者文章
热门