读源码的第三天-StopWatch

读源码的第三天-StopWatch

阅读SpringApplication类的run()方法,我们会注意到一个StopWatch,它是干什么的呢?本节中我们来探究一下。

	public ConfigurableApplicationContext run(String... args) {
    
    
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
         ...
         stopWatch.stop();
    }

定义

StopWatch是一个秒表,允许对多个任务进行计时,支持获取总运行时间和打印每个任务的运行时间。

代码演示

public class Application {
    
    

    public static void main(String[] args) throws InterruptedException {
    
    
        StopWatch stopWatch = new StopWatch();
        
        stopWatch.start("task1");
        Thread.sleep(3000);
        stopWatch.stop();
        
        stopWatch.start("task2");
        Thread.sleep(5000);
        stopWatch.stop();
        
        System.out.println(stopWatch.prettyPrint());
        System.out.println("总运行时间:"+stopWatch.getTotalTimeMillis() / 1000.0+"seconds");
    }
}

运行结果

StopWatch '': running time = 8000489386 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
3000398506  038%  task1
5000090880  062%  task2

总运行时间:8.0seconds

优点

  • 隐藏{@link System#nanoTime()}的使用,从而提高了应用程序代码的可读性并减少了计算错误的可能性。
  • 支持对多个任务进行计时
  • 提供prettyPrint()方法,显示结果美观,并且可显示百分比

不足

  • 虽说允许对多个任务进行计时,但要求多个任务串行,任务2要执行,必须等到任务1执行stop()方法后方可。否则将会报错Can't start StopWatch: it's already running

  • 没有提供用于获取指定任务运行时间的方法。通过源码可发现StopWatch使用LinkedList存储各任务及运行时间,众所周知,LinkedList查询效率较低,或许StopWatch作者出于性能原因考虑,故意未提供该方法。

  • 此对象并非设计为线程安全的,未使用synchronization。

注意

  • StopWatch通常用于在开发过程中验证性能,请不要将其作为生产应用程序的一部分。

有感

或许你可以优化该类,使其支持并行任务,实现线程安全,优化任务时间查询。