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日

相关文章

  • 为Xamarin.Forms的导航栏增加搜索功能

    为 Xamarin.Forms 的导航栏增加搜索功能攻略 在 Xamarin.Forms 中,可以为导航栏增加搜索功能,以便用户可以快速查找所需的内容。本攻略将介绍如何为 Xamarin.Forms 的导航栏增加搜索功能。 步骤 步骤1:创建搜索页 首先,需要创建一个搜索页,以便用户可以在其中输入搜索关键字。可以使用以下代码创建一个名为 SearchPage…

    C# 2023年5月17日
    00
  • 基于C#实现获取本地磁盘目录

    下面是详细的讲解“基于C#实现获取本地磁盘目录”的完整攻略。 背景介绍 在 C# 开发中,有时需要获取本地磁盘目录的信息,比如磁盘名称、总大小、可用空间等。这些信息可以用来进行磁盘管理和监控,是非常重要的功能。 实现步骤 下面介绍实现步骤: 步骤1:引用命名空间 在 C# 代码中,获取本地磁盘目录需要用到 System.IO 命名空间。因此需要在代码中引用该…

    C# 2023年6月2日
    00
  • c# 实现发送邮件的功能

    以下是详细讲解c#实现发送邮件的功能的完整攻略: 1. 准备工作 在使用C#发送邮件前,需要在电脑上安装SMTP服务,可通过“控制面板”->“程序和功能”->“启用或关闭Windows功能”下的“Internet信息服务”。 2. 引用命名空间 在代码前要先引用System.Net和System.Net.Mail两个命名空间,其中System.N…

    C# 2023年5月14日
    00
  • c# 用ICSharpCode组件压缩文件

    下面是详细讲解“c# 用ICSharpCode组件压缩文件”的完整攻略。 一、ICSharpCode组件简介 ICSharpCode是一个.NET开发者常用的开源项目,其中包括ICSharpCode.SharpZipLib组件,可以用来对压缩文件进行操作,包括压缩和解压缩。如果想要在C#中实现压缩和解压缩,可以通过使用ICSharpCode.SharpZip…

    C# 2023年6月1日
    00
  • 轻松学习C#的哈希表

    轻松学习C#的哈希表攻略 什么是哈希表 哈希表是一种通过哈希函数来实现的数据结构。哈希函数将每个键(key)映射到值(value),使得我们可以通过键快速的访问到对应的值。使用哈希表可以大幅提高数据的访问速度,具有极高的效率。 如何创建一个哈希表 在C#中,可以通过HashTable类来创建一个哈希表。创建方法如下: //创建一个哈希表 Hashtable …

    C# 2023年5月31日
    00
  • asp.net 需要登陆的网站上下载网页源代码和文件

    要下载需要登陆的网站的源代码和文件,我们可以使用以下步骤: 安装浏览器扩展程序 我们可以搜索并安装一些浏览器扩展程序,如“EditThisCookie”或“Get Cookies”,这些扩展程序可以帮助我们获取网站的cookie信息,用以模拟登陆状态。 登陆并获取cookie信息 使用浏览器登陆需要下载的网站,进入登陆状态后,打开扩展程序,获取cookie信…

    C# 2023年5月31日
    00
  • C# Stream.ReadByte – 从流中读取一个字节

    C# 中的 Stream 类提供了许多方法来读取和写入字节流,其中包括 ReadByte 方法。ReadByte 方法的作用是从当前流中读取下一个字节并提升流的位置一个字节,如果流已经结束,则返回 -1。 使用方法的完整攻略如下: 语法 public virtual int ReadByte(); 返回值 返回读取的字节的整数表示形式,如果已经读取到流的末尾…

    C# 2023年4月19日
    00
  • Asp.Net Core配置多环境log4net配置文件的全过程

    在 ASP.NET Core 项目中,使用 log4net 记录日志是一种常见的方式。在多环境下,我们需要为每个环境配置不同的 log4net 配置文件。以下是 ASP.NET Core 配置多环境 log4net 配置文件的全过程: 步骤一:添加 log4net 包 首先,需要在 ASP.NET Core 项目中添加 log4net 包。可以使用 NuGe…

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