该类在spring源码中
这个项目的 org.springframework.util.StopWatch 有兴趣可以自己看,我也是刚开始看源码,还有很多不足的地方
以下是该类的具体源码:
package org.springframework.util;
import java.text.NumberFormat;
import java.util.linkedList;
import java.util.List;
import org.springframework.lang.Nullable;
public class StopWatch {
private final String id;
// 保留任务列表
private boolean keepTaskList = true;
// 任务列表
private final List taskList = new linkedList<>();
private long startTimeMillis;
@Nullable
private String currentTaskName;
// 上次任务信息
@Nullable
private TaskInfo lastTaskInfo;
//任务计数
private int taskCount;
private long totalTimeMillis;
public StopWatch() {
this("");
}
public StopWatch(String id) {
this.id = id;
}
public String getId() {
return this.id;
}
public void setKeepTaskList(boolean keepTaskList) {
this.keepTaskList = keepTaskList;
}
public void start() throws IllegalStateException {
start("");
}
public void start(String taskName) throws IllegalStateException {
if (this.currentTaskName != null) {
throw new IllegalStateException("Can't start StopWatch: it's already running");//“无法启动秒表:它已在运行”
}
this.currentTaskName = taskName;
this.startTimeMillis = System.currentTimeMillis();
}
public void stop() throws IllegalStateException {
if (this.currentTaskName == null) {
throw new IllegalStateException("Can't stop StopWatch: it's not running");//“无法停止秒表:它没有运行”
}
long lastTime = System.currentTimeMillis() - this.startTimeMillis;
this.totalTimeMillis += lastTime;
this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);
if (this.keepTaskList) {
this.taskList.add(this.lastTaskInfo);
}
++this.taskCount;
this.currentTaskName = null;
}
public boolean isRunning() {
return (this.currentTaskName != null);
}
@Nullable
public String currentTaskName() {
return this.currentTaskName;
}
public long getLastTaskTimeMillis() throws IllegalStateException {
if (this.lastTaskInfo == null) {
throw new IllegalStateException("No tasks run: can't get last task interval");//“未运行任务:无法获取上次任务间隔”
}
return this.lastTaskInfo.getTimeMillis();
}
public String getLastTaskName() throws IllegalStateException {
if (this.lastTaskInfo == null) {
throw new IllegalStateException("No tasks run: can't get last task name");//“未运行任务:无法获取上次任务名称”
}
return this.lastTaskInfo.getTaskName();
}
public TaskInfo getLastTaskInfo() throws IllegalStateException {
if (this.lastTaskInfo == null) {
throw new IllegalStateException("No tasks run: can't get last task info");//“未运行任务:无法获取上次任务信息”
}
return this.lastTaskInfo;
}
public long getTotalTimeMillis() {
return this.totalTimeMillis;
}
public double getTotalTimeSeconds() {
return this.totalTimeMillis / 1000.0;
}
public int getTaskCount() {
return this.taskCount;
}
public TaskInfo[] getTaskInfo() {
if (!this.keepTaskList) {
throw new UnsupportedOperationException("Task info is not being kept!");//“未保留任务信息!”
}
return this.taskList.toArray(new TaskInfo[0]);
}
public String shortSummary() {
//“秒表”:运行时间(毫秒)=
return "StopWatch '" + getId() + "': running time (millis) = " + getTotalTimeMillis();
}
public String prettyPrint() {
StringBuilder sb = new StringBuilder(shortSummary());
sb.append('n');
if (!this.keepTaskList) {
sb.append("No task info kept");//“未保存任务信息”
}
else {
sb.append("-----------------------------------------n");
sb.append("ms % Task namen");//ms%任务名称n
sb.append("-----------------------------------------n");
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMinimumIntegerDigits(5);
nf.setGroupingUsed(false);
NumberFormat pf = NumberFormat.getPercentInstance();
pf.setMinimumIntegerDigits(3);
pf.setGroupingUsed(false);
for (TaskInfo task : getTaskInfo()) {
sb.append(nf.format(task.getTimeMillis())).append(" ");
sb.append(pf.format(task.getTimeSeconds() / getTotalTimeSeconds())).append(" ");
sb.append(task.getTaskName()).append("n");
}
}
return sb.toString();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(shortSummary());
if (this.keepTaskList) {
for (TaskInfo task : getTaskInfo()) {
sb.append("; [").append(task.getTaskName()).append("] took ").append(task.getTimeMillis());
long percent = Math.round((100.0 * task.getTimeSeconds()) / getTotalTimeSeconds());
sb.append(" = ").append(percent).append("%");
}
}
else {
sb.append("; no task info kept");//; 没有保存任务信息
}
return sb.toString();
}
public static final class TaskInfo {
private final String taskName;
private final long timeMillis;
TaskInfo(String taskName, long timeMillis) {
this.taskName = taskName;
this.timeMillis = timeMillis;
}
public String getTaskName() {
return this.taskName;
}
public long getTimeMillis() {
return this.timeMillis;
}
public double getTimeSeconds() {
return (this.timeMillis / 1000.0);
}
}
}
以下是我的使用示例:
import org.junit.Test;
import org.springframework.util.StopWatch;
public class StopWatchTest {
@Test
public void no1() throws InterruptedException {
StopWatch stopWatch = new StopWatch("MyStopWatch");
String id = stopWatch.getId();
System.out.println("秒表id:" + id);
String s = stopWatch.currentTaskName();
System.out.println("当前任务名称" + s);
boolean running = stopWatch.isRunning();
System.out.println("是否正在运行:" + running);
String s1 = stopWatch.prettyPrint();
System.out.println("运行时间:" + s1);
//开始任务 命名为MyStopWatchTest
stopWatch.start("MyStopWatchTest");
Thread.sleep(6000 * 5);
String s4 = stopWatch.currentTaskName();
System.out.println("当前任务名称" + s4);
//任务停止
stopWatch.stop();
//开始任务 命名为MyStopWatchTest2
stopWatch.start("MyStopWatchTest2");
Thread.sleep(6000 * 5);
String s5 = stopWatch.currentTaskName();
System.out.println("当前任务名称" + s5);
//任务停止
stopWatch.stop();
String s3 = stopWatch.currentTaskName();
System.out.println("当前任务名称" + s3);
String s2 = stopWatch.prettyPrint();
System.out.println("运行时间:" + s2);
}
}
以下是示例输出:
秒表id:MyStopWatch
当前任务名称null
是否正在运行:false
运行时间:StopWatch 'MyStopWatch': running time (millis) = 0
-----------------------------------------
ms % Task name
-----------------------------------------
当前任务名称MyStopWatchTest
当前任务名称MyStopWatchTest2
当前任务名称null
运行时间:StopWatch 'MyStopWatch': running time (millis) = 60001
-----------------------------------------
ms % Task name
-----------------------------------------
30000 050% MyStopWatchTest
30001 050% MyStopWatchTest2
总结:
该工具类可以在我们应用程序测试时使用,通过任务名称的形式区分调用不同方法调用时的使用时间,以及整个应用程序的用时,非常方便的区分各个方法的用时,不在需要自己获取方法开始时间和结束时间然后计算



