spring学习分享1(spring工具类-秒表)

今天看spring源码工具类时发现一个好用的东西所以分享出来

该类在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;

/**
 * Simple stop watch, allowing for timing of a number of tasks,
 * exposing total running time and running time for each named task.
 *
 * <p>Conceals use of {@code System.currentTimeMillis()}, improving the
 * readability of application code and reducing the likelihood of calculation errors.
 *
 * <p>Note that this object is not designed to be thread-safe and does not
 * use synchronization.
 *
 * <p>This class is normally used to verify performance during proof-of-concepts
 * and in development, rather than as part of production applications.
 *
 * 简单的秒表,允许对大量任务进行计时,显示每个命名任务的总运行时间和运行时间。
 * <p>隐藏{@code System.currentTimeMillis()}的使用,提高应用程序代码的可读性并减少计算错误的可能性。
 * <p>请注意,此对象不是为线程安全而设计的,并且不使用同步。
 * <p>此类通常用于在概念验证和开发过程中验证性能,而不是作为生产应用程序的一部分。
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @since May 2, 2001
 */
public class StopWatch {

   /**
    * Identifier of this stop watch.
    * Handy when we have output from multiple stop watches
    * and need to distinguish between them in log or console output.
    * 此秒表的标识符。
    * 当我们有来自多个秒表的输出,并且需要在日志或控制台输出中区分它们时,这非常方便。
    */
   private final String id;

   // 保留任务列表
   private boolean keepTaskList = true;

   // 任务列表
   private final List<TaskInfo> taskList = new LinkedList<>();

   /** Start time of the current task. 当前任务的开始时间。 */
   private long startTimeMillis;

   /** Name of the current task. 当前任务的名称。*/
   @Nullable
   private String currentTaskName;

   // 上次任务信息
   @Nullable
   private TaskInfo lastTaskInfo;

   //任务计数
   private int taskCount;

   /** Total running time. 总运行时间。*/
   private long totalTimeMillis;


   /**
    * 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.
    *
    * 使用给定id构造新秒表。不启动任何任务。
    * @param id 此秒表的标识符。
    * 当我们有来自多个秒表的输出并且需要区分它们时,它非常方便。
    */
   public StopWatch(String id) {
      this.id = id;
   }


   /**
    * Return the id of this stop watch, as specified on construction.
    * @return the id (empty String by default)
    * @since 4.2.2
    * @see #StopWatch(String)
    *
    * 返回此秒表的id,如施工图所示。
    * @return id(默认为空字符串)
    */
   public String getId() {
      return this.id;
   }

   /**
    * Determine whether the TaskInfo array is built over time. Set this to
    * "false" when using a StopWatch for millions of intervals, or the task
    * info structure will consume excessive memory. Default is "true".
    *
    * 确定TaskInfo数组是否随时间构建。
    * 在数百万次使用秒表时,将此设置为“false”,否则任务信息结构将消耗过多内存。默认值为“true”。
    */
   public void setKeepTaskList(boolean keepTaskList) {
      this.keepTaskList = keepTaskList;
   }


   /**
    * Start an unnamed task. The results are undefined if {@link #stop()}
    * or timing methods are called without invoking this method.
    * @see #stop()
    *
    * 启动一个未命名的任务。如果在不调用此方法的情况下调用{@link #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()
    *
    * 启动命名任务。如果在不调用此方法的情况下调用{@link #stop())}或计时方法,则结果是未定义的。
    * @param taskName 要启动的任务的名称
    */
   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();
   }

   /**
    * 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()
    *
    * 将当前任务置于顶部。如果在不调用至少一对的情况下调用计时方法,则结果是未定义的
    * {@code start()} / {@code stop()} 方法.
    */
   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;
   }

   /**
    * Return whether the stop watch is currently running.
    * @see #currentTaskName()
    *
    * 返回秒表当前是否正在运行。
    */
   public boolean isRunning() {
      return (this.currentTaskName != null);
   }

   /**
    * Return the name of the currently running task, if any.
    * @since 4.2.2
    * @see #isRunning()
    *
    * 返回当前正在运行的任务的名称(如果有)。
    */
   @Nullable
   public String currentTaskName() {
      return this.currentTaskName;
   }


   /**
    * Return the time taken by the last task.
    * 返回上一个任务所用的时间。
    */
   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();
   }

   /**
    * Return the name of the last task.
    * 返回最后一个任务的名称。
    */
   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();
   }

   /**
    * Return the last task as a TaskInfo object.
    * 将上一个任务作为TaskInfo对象返回。
    */
   public TaskInfo getLastTaskInfo() throws IllegalStateException {
      if (this.lastTaskInfo == null) {
         throw new IllegalStateException("No tasks run: can't get last task info");//“未运行任务:无法获取上次任务信息”
      }
      return this.lastTaskInfo;
   }


   /**
    * Return the total time in milliseconds for all tasks.
    * 返回所有任务的总时间(以毫秒为单位)。
    */
   public long getTotalTimeMillis() {
      return this.totalTimeMillis;
   }

   /**
    * Return the total time in seconds for all tasks.
    * 返回所有任务的总时间(秒)。
    */
   public double getTotalTimeSeconds() {
      return this.totalTimeMillis / 1000.0;
   }

   /**
    * Return the number of tasks timed.
    * 返回已计时的任务数。
    */
   public int getTaskCount() {
      return this.taskCount;
   }

   /**
    * Return an array of the data for tasks performed.
    * 返回所执行任务的数据数组。
    */
   public TaskInfo[] getTaskInfo() {
      if (!this.keepTaskList) {
         throw new UnsupportedOperationException("Task info is not being kept!");//“未保留任务信息!”
      }
      return this.taskList.toArray(new TaskInfo[0]);
   }


   /**
    * 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.
    * 返回一个字符串,其中包含一个描述所执行的所有任务的表。
    * 对于自定义报告,请调用getTaskInfo()并直接使用任务信息。
    */
   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");//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();
   }

   /**
    * Return an informative string describing all tasks performed
    * For custom reporting, call {@code getTaskInfo()} and use the task info directly.
    *
    * 返回描述为自定义报告执行的所有任务的信息字符串,调用{@code getTaskInfo()}并直接使用任务信息。
    */
   @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();
   }


   /**
    * Inner class to hold data about one task executed within the stop watch.
    * 内部类,用于保存有关秒表中执行的一个任务的数据。
    */
   public static final class TaskInfo {

      private final String taskName;

      private final long timeMillis;

      TaskInfo(String taskName, long timeMillis) {
         this.taskName = taskName;
         this.timeMillis = timeMillis;
      }

      /**
       * Return the name of this task.
       * 返回此任务的名称。
       */
      public String getTaskName() {
         return this.taskName;
      }

      /**
       * Return the time in milliseconds this task took.
       * 返回此任务所用的时间(以毫秒为单位)。
       */
      public long getTimeMillis() {
         return this.timeMillis;
      }

      /**
       * Return the time in seconds this task took.
       * 返回此任务所用的时间(以秒为单位)。
       */
      public double getTimeSeconds() {
         return (this.timeMillis / 1000.0);
      }
   }

}

以下是我的使用示例:

import org.junit.Test;
import org.springframework.util.StopWatch;

/**
 * <T>User:cf</T>
 * <T>Description:秒表测试</T>
 * <T>Create time:2021/10/14 10:07</T>
 * <T>Company: dolph-tech</T>
 * <T>Update record(who,time,message):</T>
 * <T>date 2021年 10月 14日
 */
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
 

 总结:

该工具类可以在我们应用程序测试时使用,通过任务名称的形式区分调用不同方法调用时的使用时间,以及整个应用程序的用时,非常方便的区分各个方法的用时,不在需要自己获取方法开始时间和结束时间然后计算

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值