Spring Boot源码实现StopWatch优雅统计耗时

首先我们先来介绍一下StopWatch是什么。

StopWatch是Spring Framework中用来计时的工具类,其设计思想源于Commons-lang中的StopWatch。其主要功能是帮助我们在开发过程中进行代码耗时的统计,方便我们进行性能优化。StopWatch提供了一系列操作,例如开始计时、停止计时以及记录过程中每个计时点的时间等。

接下来,我们就来详细讲解Spring Boot源码中StopWatch的实现过程。

1.定义类

首先,我们需要定义一个类来创建StopWatch对象。在Spring Boot中,我们可以通过以下方式来定义:

package org.springframework.boot;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class StopWatch {

    private String id;

    private boolean keepTaskList = true;

    private final List<TaskInfo> taskList = new ArrayList<>();

    private long startTimeMillis;

    private boolean running;

    private String currentTaskName;

    private TaskInfo lastTaskInfo;

    private int taskCount;

    private long totalTimeMillis;


    public StopWatch() {
        this("");
    }


    public StopWatch(String id) {
        this.id = (id != null ? id : "");
    }

    public String getId() {
        return this.id;
    }

}

2.开始计时

接着,我们需要在StopWatch中实现开始计时的方法。代码如下:

public void start() throws IllegalStateException {
    synchronized (this) {
        if (this.running) {
            throw new IllegalStateException("Can't start StopWatch: it's already running");
        }
        this.startTimeMillis = System.currentTimeMillis();
        this.running = true;
        this.currentTaskName = null;
        this.taskList.clear();
    }
}

在上述代码中,我们通过synchronized锁定当前实例,防止多线程环境下对StopWatch的可见性问题。然后我们判断当前是否正在计时,如果正在计时,则抛出IllegalStateException异常,否则开始计时。同时也初始化了一些状态,例如当前的任务名称和任务列表等。

3.停止计时

接下来,我们需要在StopWatch中实现停止计时的方法。代码如下:

public void stop() throws IllegalStateException {
    synchronized (this) {
        if (!this.running) {
            throw new IllegalStateException("Can't stop StopWatch: it's not running");
        }
        long lastTaskTimeMillis = System.currentTimeMillis() - this.startTimeMillis;
        this.totalTimeMillis += lastTaskTimeMillis;
        this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTaskTimeMillis);
        this.taskList.add(this.lastTaskInfo);
        ++this.taskCount;
        this.running = false;
        this.currentTaskName = null;
    }
}

与开始计时类似,我们也需要对当前实例进行锁定。然后我们判断当前是否正在计时,如果没有在计时,就抛出异常。这里我们记录了最后一次任务的时间,累加到总时间中,并且将最后一个任务的信息添加到任务列表中。

4.记录任务信息

在StopWatch中,我们还需要记录过程中每个计时点的时间。代码如下:

public void lap(String taskName) throws IllegalStateException {
    synchronized (this) {
        if (!this.running) {
            throw new IllegalStateException("Can't lap StopWatch: it's not running");
        }
        long lastTaskTimeMillis = System.currentTimeMillis() - this.startTimeMillis;
        this.totalTimeMillis += lastTaskTimeMillis;
        this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTaskTimeMillis);
        this.taskList.add(this.lastTaskInfo);
        ++this.taskCount;
        this.currentTaskName = taskName;
        this.startTimeMillis = System.currentTimeMillis();
    }
}

在这里,我们首先判断当前是否正在计时,如果没有在计时,则抛出异常。记录最后一个任务的时间,然后将最后一个任务的信息添加到任务列表中,并累加到总时间中。最后,我们将当前任务名称设置为指定的任务名称,并重新开始计时。

5.获取总时间

最后,我们需要在StopWatch中获取总时间。代码如下:

public long getTotalTimeMillis() {
    synchronized (this) {
        return this.totalTimeMillis;
    }
}

在这里,我们只需要返回记录的总时间即可。

至此,我们已经完成了Spring Boot源码中StopWatch的实现。接下来,我们可以通过以下两个示例来演示如何使用StopWatch:

示例1:统计方法执行时间

StopWatch stopWatch = new StopWatch();
stopWatch.start();

// 执行耗时任务
Thread.sleep(1000);

stopWatch.stop();
System.out.println("方法总耗时:" + stopWatch.getTotalTimeMillis() + "ms");

在这里,我们新建了一个StopWatch实例,开始计时,然后执行耗时任务,最后停止计时,并输出总耗时时间。

示例2:统计多个任务的处理时间

StopWatch stopWatch = new StopWatch();
stopWatch.start("任务一");
Thread.sleep(1000);
stopWatch.stop();

stopWatch.start("任务二");
Thread.sleep(2000);
stopWatch.stop();

System.out.println("任务一耗时:" + stopWatch.getTotalTimeMillis() + "ms");
System.out.println("任务二耗时:" + stopWatch.getLastTaskTimeMillis() + "ms");

在这里,我们通过StopWatch来统计多个任务的处理时间。首先,我们开始计时第一个任务,并执行任务,最后停止计时。然后开始计时第二个任务,执行任务,最后停止计时。最后,我们输出第一个任务和第二个任务的处理时间。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot源码实现StopWatch优雅统计耗时 - Python技术站

(0)
上一篇 2023年6月6日
下一篇 2023年6月6日

相关文章

  • ASP.NET数组删除重复值实现代码

    下面为您详细讲解“ASP.NET数组删除重复值实现代码”的攻略过程: 1. 准备工作 首先,在进行数组删除重复值之前,需定义一个原始数组,此处用int类型数组为例: int[] array = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3}; 而在进行删除后,需定义一个新的数组来存储结果: int[] newArray = new int[ar…

    C# 2023年5月31日
    00
  • C#获取DataTable对象状态DataRowState

    获取DataTable对象状态DataRowState攻略 在C#中,DataTable(数据表)是常用的数据存储和处理方式。在使用DataTable的过程中,需要了解DataTable对象的状态DataRowState,以进行数据操作。 1. DataTable对象的状态DataRowState 在DataTable的数据处理中,每个DataRow(行)都…

    C# 2023年5月15日
    00
  • C#解析JSON实例

    下面是详细讲解“C#解析JSON实例”的完整攻略: 什么是JSON JSON(JavaScript Object Notation)是一种数据格式,用于交换数据。它比XML更容易阅读,也更容易解析。JSON数据格式由键值对构成,键和值之间用冒号分隔,值的数据类型可以是字符串,数字,布尔值,数组,对象等。例如: { "name": &quo…

    C# 2023年5月31日
    00
  • C#中反射和扩展方法如何运用

    反射是C#语言中非常重要的一个特性,它可以在运行时动态地获取程序集中的各种信息(例如类型、属性、方法等),并且可以在不知道类型的情况下与它进行交互。扩展方法则是我们定义的一组静态方法,它们能够对现有的类进行扩展,而不用修改原来的代码。本次攻略将详细讲解C#中反射和扩展方法的使用方式,并通过两个示例来说明。 反射的使用 获取类型信息 在C#中,我们可以通过反射…

    C# 2023年6月6日
    00
  • C#中把DataTable、Dataset转Json数据

    转化 DataTable 或者 Dataset 为 Json 数据可以借助于第三方库,比如 Newtonsoft.Json 库。以下是具体的示例攻略: 1. 使用 Newtonsoft.Json 转换单个 DataTable 在 Visual Studio 等 IDE 中,在项目中添加 Newtonsoft.Json 库,或者通过 NuGet 安装 给 Da…

    C# 2023年5月31日
    00
  • ASP.NET Core处理管道的深入理解

    ASP.NET Core处理管道的深入理解 在本攻略中,我们将深入理解ASP.NET Core处理管道的工作原理和使用方法。我们将介绍ASP.NET Core处理管道的组成部分、中间件的作用和使用方法,并提供两个示例说明。 处理管道的组成部分 ASP.NET Core处理管道由以下三个组成部分组成: 请求管道:处理HTTP请求的管道。 响应管道:处理HTTP…

    C# 2023年5月16日
    00
  • jquery 学习之一 对象访问

    下面是关于“jQuery学习之一对象访问”的完整攻略,包含两个示例。 1. jQuery对象访问简介 jQuery是一种流行的JavaScript库,用于简化JavaScript编程。jQuery提供了一组强大的API,用于访问和操作HTML元素、CSS样式和事件等。在jQuery中,可以使用选择器来选择HTML元素,并使用jQuery对象来访问和操作这些元…

    C# 2023年5月15日
    00
  • 基于ABP架构开发的.Net Core项目部署到IIS问题汇总

    基于ABP架构开发的.Net Core项目部署到IIS问题汇总 ABP框架是一个基于DDD的开源Web应用程序框架,它使用最新的ASP.NET Core技术。在本攻略中,我们将讨论如何将基于ABP架构开发的.Net Core项目部署到IIS,并总结一些常见问题及其解决方案。 步骤一:安装.NET Core Runtime和.NET Core Hosting …

    C# 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部