背景
在查看spring boot的自动装配的时候,发现其中用到了StopWatch,阅读源码之后,发觉这个工具类可以之后为我们所用(查看调用任务耗时的情况)
来源
jar包:spring-core
代码包:org.springframework.util(util里面还有很多其他的工具类,之后会写更多的博客加以阐述)
函数列表
重要代码
构造
/**
* Construct a new stop watch. Does not start any task.
*/
public StopWatch() {
this("");
}
/**
* Construct a new stop watch with the given id.
* Does not start any task.
* @param id identifier for this stop watch.
* Handy when we have output from multiple stop watches
* and need to distinguish between them.
*/
public StopWatch(String id) {
this.id = id;
}
构造函数:
- 可以传入id作为区分
start
/**
* Start an unnamed task. The results are undefined if {@link #stop()}
* or timing methods are called without invoking this method.
* @see #stop()
*/
public void start() throws IllegalStateException {
start("");
}
/**
* Start a named task. The results are undefined if {@link #stop()}
* or timing methods are called without invoking this method.
* @param taskName the name of the task to start
* @see #stop()
*/
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();
}
- 可以传入任务名称
- 以任务名称是否为空来决定这个任务是不是开始过(跟我之前做播放器的时候用的思路是一样的)
- 记录currentTimeMills,也就是系统的毫秒时间
stop
/**
* Stop the current task. The results are undefined if timing
* methods are called without invoking at least one pair
* {@code start()} / {@code stop()} methods.
* @see #start()
*/
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;
}
- 记录本次任务的耗时
- 记录本次任务的信息(发现任务信息是一个串,说明StopWatch是可以作为一条任务链去使用的)
- 记录任务次数
打印(nice的部分)
/**
* Return a short description of the total running time.
*/
public String shortSummary() {
return "StopWatch '" + getId() + "': running time (millis) = " + getTotalTimeMillis();
}
/**
* Return a string with a table describing all tasks performed.
* For custom reporting, call getTaskInfo() and use the task info directly.
*/
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 name\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();
}
/**
* Return an informative string describing all tasks performed
* For custom reporting, call {@code getTaskInfo()} and use the task info directly.
*/
@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();
}
- 概要打印
- 详细打印toString
- 还有一个pretty的打印(这样非常容易进行每个任务耗时的观察,在封装go语言框架的时候可以用到)
实战
import org.springframework.util.StopWatch;
public class StopWatchDemo {
public static void main(String[] args) throws InterruptedException {
StopWatch stopWatch = new StopWatch("我的检测器");
stopWatch.start("任务1");
Thread.sleep(1000);
stopWatch.stop();
stopWatch.start("任务2");
Thread.sleep(2000);
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
}
}