SpringBoot 启动过程中使用到了StopWatch 对象,被称为秒表对象。这个对象针对任务提供了任务执行时间,总任务时间方法
优点
增加了代码可读性,隐藏了System.nanoTime()实现细节。降低了代码出错率
简单使用方法
public static void main(String[] args) throws InterruptedException {
// 创建秒表对象
StopWatch stopWatch = new StopWatch("对象ID-标识");
// 启动秒表
stopWatch.start("任务名称");
// 模拟业务运行时间-停留两秒
TimeUnit.SECONDS.sleep(2);
// 停止秒表
stopWatch.stop();
/**
* 获取最后一个任务毫秒
*/
System.out.println(stopWatch.getLastTaskTimeMillis());
/**
* 获取最后一个任务秒
*/
System.out.println(stopWatch.getLastTaskInfo().getTimeSeconds());
/**
* 获取最后一个任务纳秒
*/
System.out.println(stopWatch.getLastTaskInfo().getTimeNanos());
/**
* 获取任务数组
*/
System.out.println(stopWatch.getTaskInfo());
}
时间格式化
转换方法
public static String msTime2Duration(long msDuration) {
//使用lang3工具类
String durationStr = DurationFormatUtils.formatDuration(msDuration, "d'天'H'时'm'分's'秒'");
durationStr = durationStr.replace("0天0时0分", "");
durationStr = durationStr.replace("0天0时", "");
durationStr = durationStr.replace("0天", "");
return durationStr;
}
如果缺少JAR包
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
StopWatch对象源码解析
public class StopWatch {
// ID标识符
private final String id;
// 是否流程留存任务历史
private boolean keepTaskList = true;
// 任务集合如果keepTaskList为true,每次任务都会添加
private final List<TaskInfo> taskList = new LinkedList<>();
/** 任务开始时间 */
private long startTimeNanos;
/** 任务名称 */
@Nullable
private String currentTaskName;
// 最后一次执行的任务
@Nullable
private TaskInfo lastTaskInfo;
// 任务总数
private int taskCount;
/** 所有任务运行总时长 */
private long totalTimeNanos;
/**
* 无参构造器,秒表的ID为空字符串
*/
public StopWatch() {
this("");
}
/**
* 自定义ID
*/
public StopWatch(String id) {
this.id = 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.startTimeNanos = System.nanoTime();
}
/**
* 停止秒表
*/
public void stop() throws IllegalStateException {
if (this.currentTaskName == null) {
throw new IllegalStateException("Can't stop StopWatch: it's not running");
}
long lastTime = System.nanoTime() - this.startTimeNanos;
this.totalTimeNanos += 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 getLastTaskTimeNanos() throws IllegalStateException {
if (this.lastTaskInfo == null) {
throw new IllegalStateException("No tasks run: can't get last task interval");
}
return this.lastTaskInfo.getTimeNanos();
}
/**
* 获取最后一个任务的毫秒
*/
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 getTotalTimeNanos() {
return this.totalTimeNanos;
}
/**
* 获取总任务时长毫秒
*/
public long getTotalTimeMillis() {
return nanosToMillis(this.totalTimeNanos);
}
/**
* 获取总任务市场秒
*/
public double getTotalTimeSeconds() {
return nanosToSeconds(this.totalTimeNanos);
}
/**
* 获取总任务数量
*/
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 = " + getTotalTimeNanos() + " ns";
}
/**
* 打印任务信息
*/
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("ns % Task name\n");
sb.append("---------------------------------------------\n");
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMinimumIntegerDigits(9);
nf.setGroupingUsed(false);
NumberFormat pf = NumberFormat.getPercentInstance();
pf.setMinimumIntegerDigits(3);
pf.setGroupingUsed(false);
for (TaskInfo task : getTaskInfo()) {
sb.append(nf.format(task.getTimeNanos())).append(" ");
sb.append(pf.format((double) task.getTimeNanos() / getTotalTimeNanos())).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.getTimeNanos()).append(" ns");
long percent = Math.round(100.0 * task.getTimeNanos() / getTotalTimeNanos());
sb.append(" = ").append(percent).append("%");
}
}
else {
sb.append("; no task info kept");
}
return sb.toString();
}
private static long nanosToMillis(long duration) {
return TimeUnit.NANOSECONDS.toMillis(duration);
}
private static double nanosToSeconds(long duration) {
return duration / 1_000_000_000.0;
}
/**
* 任务对象信息
*/
public static final class TaskInfo {
private final String taskName;
private final long timeNanos;
TaskInfo(String taskName, long timeNanos) {
this.taskName = taskName;
this.timeNanos = timeNanos;
}
/**
* Get the name of this task.
*/
public String getTaskName() {
return this.taskName;
}
/**
* Get the time in nanoseconds this task took.
* @since 5.2
* @see #getTimeMillis()
* @see #getTimeSeconds()
*/
public long getTimeNanos() {
return this.timeNanos;
}
/**
* Get the time in milliseconds this task took.
* @see #getTimeNanos()
* @see #getTimeSeconds()
*/
public long getTimeMillis() {
return nanosToMillis(this.timeNanos);
}
/**
* Get the time in seconds this task took.
* @see #getTimeMillis()
* @see #getTimeNanos()
*/
public double getTimeSeconds() {
return nanosToSeconds(this.timeNanos);
}
}
}
完结
以上就是SpringBoot 中 StopWatch 对象的具体使用方式和源码解释了,如果有哪里说的不对。可以评论探讨