首先我们先来介绍一下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技术站