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日

相关文章

  • C# wx获取token的基本方法

    C# wx获取token的基本方法 什么是Token? 在微信公众号开发中,Token是指在微信公众平台上,通过接口调用获取到的一个用于对当前公众号进行身份验证的字符串。 获取Token的基本方法 获取Token的基本方法是向微信服务器发送HTTP请求。发送请求的URL是: https://api.weixin.qq.com/cgi-bin/token?gr…

    C# 2023年5月31日
    00
  • 详细分析c# 运算符重载

    详细分析C#运算符重载 C#运算符重载是一种在类定义中定义特定运算符的方式。通过对运算符进行重载,我们可以为自定义类型定义自定义算术和逻辑行为。本文将介绍如何实现C#运算符重载,并提供两个实际的示例。 1、什么是C#运算符重载 在C#中,一些运算符如 +、-、*、/、< 等都是具有预定义行为的。当我们对 int、float、double、string等…

    C# 2023年6月7日
    00
  • win8 Could not load type System.ServiceModel.Activation.HttpModule 错误解决方案

    下面是关于“win8CouldnotloadtypeSystem.ServiceModel.Activation.HttpModule错误解决方案”的完整攻略,包含两个示例。 1. 错误描述 在Windows 8操作系统上,当使用IIS 8.0托管WCF服务时,可能会出现以下错误: Could not load type ‘System.ServiceMod…

    C# 2023年5月15日
    00
  • 一个可用于生产项目 基于 .NET 6 自研ORM

    Fast Framework 作者 Mr-zhong 代码改变世界…. 一、前言 Fast Framework 基于NET6.0 封装的轻量级 ORM 框架 支持多种数据库 SqlServer Oracle MySql PostgreSql Sqlite 优点: 体积小、可动态切换不同实现类库、原生支持微软特性、流畅API、使用简单、性能高、模型数据绑定…

    C# 2023年4月27日
    00
  • C#设计模式之工厂模式

    C#设计模式之工厂模式 什么是工厂模式? 工厂模式是指为创建对象定义一个接口,让子类决定实例化哪一个类。工厂模式让一个类的实例化延迟到其子类。使用工厂模式我们可以让对象的创建和实现分离,当我们需要增加一种新的对象时,我们只需要添加一个新的具体的类和它相应的工厂类就可以了,不会对原来的代码产生太多的影响。 工厂模式的三种形式 简单工厂模式 工厂方法模式 抽象工…

    C# 2023年6月1日
    00
  • C#任务并行Parellel.For和Parallel.ForEach

    我们来详细讲解一下C#中任务并行的两个方法Parallel.For和Parallel.ForEach的使用攻略。 Parallel.For 用法 Parallel.For是C#中的一个并行任务处理方法,可以并行处理一个区间内的多个任务。其语法格式如下: Parallel.For(startIndex, endIndex, index => { // 处…

    C# 2023年6月6日
    00
  • 在ASP.NET 2.0中操作数据之六:编程设置ObjectDataSource的参数值

    操作数据是Web应用程序中最常见的任务之一。在ASP.NET 2.0之后,为了简化设置数据源和处理数据的任务,可以使用ObjectDataSource控件。本攻略将详细讲解如何编程设置ObjectDataSource的参数值。 什么是ObjectDataSource ObjectDataSource是ASP.NET用于极度简化数据访问代码的控件之一。利用Ob…

    C# 2023年5月31日
    00
  • c# winform时钟的实现代码

    下面就来详细讲解一下“c# winform时钟的实现代码”的完整攻略。 一、准备工作 1. 创建WinForm应用程序 首先,我们需要创建一个WinForm应用程序,用于显示时钟。 2. 调整窗体大小和样式 在设计模式下,拖拽一个Label控件到窗体上,并设置合适的字体、颜色和对齐方式等。 3. 添加定时器控件 右键单击工具箱中的“定时器”控件,然后在窗体上…

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