Stopwatch工具类计时器探究

Spring框架提供的StopWatch工具类是用于方便地测量代码块执行时间的,具有简单易用、性能消耗小的特点。它可以指定任务名,但一次只能开启一个任务,适合同步单线程的代码计时。在SpringBoot应用启动过程中,StopWatch被用来记录配置加载等关键步骤的耗时,帮助开发者了解应用启动时间。
摘要由CSDN通过智能技术生成

搬砖的我们 特别是Java开发的童鞋们, 经常需要通过记录开始时间和结束时间,然后通过计算差值,得到时间差,如下面的代码:

long start = System.currentTimeMillis();

long end = System.currentTimeMillis();

System.out.println("执行耗时:" + (end - start));

其实spring 这个包org.springframework.util.StopWatch的工具类也可以实现计算时间差,如下代码:

StopWatch stopWatch = new StopWatch();
// 或者指定任务名
StopWatch stopWatch = new StopWatch("name");
// 开始计时
stopWatch.start();
// 结束计时
stopWatch.stop();
// 计算时差
stopWatch.getTotalTimeSeconds();
// 计算时差

stopWatch.shortSummary();
优点:

1、Spring自带工具类,使用方便简单。

2、性能消耗相对较小,并且最大程度的保证了start与stop之间的时间记录的准确性。

3、可以指定任务名,更直观的显示记录结果。

缺点:

1、一个StopWatch实例一次只能开启一个task,不能同时start多个task,并且在该task未stop之前不能start一个新的task,必须在该task stop之后才能开启新的task,若要一次开启多个,需要new不同的StopWatch实例。
.............................................来看看Spring中stopWatch的源代码....................................................

public ConfigurableApplicationContext run(String... args) {
       (1) StopWatch stopWatch = new StopWatch();
       (2)stopWatch.start();

        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        this.configureHeadlessProperty();
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting();

        Collection exceptionReporters;
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
           (3) stopWatch.stop();
            if (this.logStartupInfo) {
               (4) (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            listeners.started(context);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

我们重点来关注上面的源代码中标注的(1),(2),(3),(4)的部分,这就是启动时监控加载个配置类的计时器,我们继续来看下(4)对应的方法:logStarted(this.getApplicationLog(), stopWatch);stopWatch作为参数传递该该方法,看看该方法具体实现:


================ logStarted()==================================================
public void logStarted(Log log, StopWatch stopWatch) {
        if (log.isInfoEnabled()) {
            log.info(this.getStartedMessage(stopWatch));
        }

    }
==============================getStartedMessage()=====================================
private StringBuilder getStartedMessage(StopWatch stopWatch) {
        StringBuilder message = new StringBuilder();
        message.append("Started ");
        message.append(this.getApplicationName());
        message.append(" in ");
        message.append(stopWatch.getTotalTimeSeconds());

        try {
            double uptime = (double)ManagementFactory.getRuntimeMXBean().getUptime() / 1000.0D;
            message.append(" seconds (JVM running for " + uptime + ")");
        } catch (Throwable var5) {
        }

        return message;
    }

Stopwatch 对程序部分代码进行计时(ms级别),适用于同步单线程代码块。StopWatch实例一次只能开启一个task,不能同时start多个task,并且在该task未stop之前不能start一个新的task,必须在该task stop之后才能开启新的task,若要一次开启多个,需要new不同的StopWatch实例
========================================================================

// 只输出运行多少秒
Stopwatch stopwatch = Stopwatch.createStarted();
stopwatch.stop();
System.out.println(stopwatch.elapsed(TimeUnit.SECONDS) + "s");
// 
   StopWatch sw = new StopWatch("test");
   sw.start("task1");
    // do something
   Thread.sleep(100);
   sw.stop();
   sw.start("task2");
   // do something
   Thread.sleep(200);
   sw.stop();
   System.out.println(sw.prettyPrint());

运行结果==================================================================
2s
StopWatch 'test': running time (millis) = 308
-----------------------------------------
ms     %     Task name
-----------------------------------------
00104  034%  task1
00204  066%  task2
============================================================================

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值