【小家java】Apache Commons-lang3提供的StopWatch执行时间监视器,以及Spring提供的StopWatch分析(上)

简介: 【小家java】Apache Commons-lang3提供的StopWatch执行时间监视器,以及Spring提供的StopWatch分析(上)

前言


编码过程中我们经常会希望得到一段代码(一个方法)的执行时间,本文将介绍两种时间监视器(秒表)来让你优雅的、灵活的处理这个问题。

Java源生方式


这种方式最最简单,最好理解,当然也是最为常用:我们自己书写。

例如:我们如果要统计一段代码的执行时间,经常会这么来写:


    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();   //获取开始时间
        //函数主体代码
        //...
        long endTime = System.currentTimeMillis(); //获取结束时间
        System.out.println("程序运行时间: " + (endTime - startTime) + "ms");
    }


大多数时候我们使用ms来表示即可,但是这么写缺乏灵活性。倘若我们要展示成纳秒、秒、甚至分钟,还得我们自己处理(把毫秒值拿来进行转换~ )


当然可能到了JDK8以后,我们这么做能变得稍微灵活一些:可以这么处理:


    public static void main(String[] args) {
        Instant start = Instant.now();
        //doSomething();
        Instant end = Instant.now();
        Duration duration = Duration.between(start, end);
        System.out.println("millis = " + duration.toMillis());
    }


这个比上面灵活度强一些。但也还是有一定的缺点:步骤稍显复杂,总体上还是不够优雅,也不是那么的灵活。


那么本文针对此问题介绍一个工具:StopWatch执行时间监视器。借助它来统计我们程序的执行时间,带给非常多的方便和优雅。


StopWatch需要依赖额外的Jar:commons-lang3或者spring-core,但因这两个Jar是Java开发中都必导的,因此依赖兼容性方面可以忽略


StopWatch有很多开源的框架都有提供类似的功能:比如Apache的commons-lang3,当然还有Spring framwork自己提供的,本文将针对此俩分别做介绍~


Commons-lang3的StopWatch


Apache提供的这个任务执行监视器功能丰富强大(比Spring的强大),灵活性强,如下经典实用案例:


    public static void main(String[] args) throws Exception {
        StopWatch watch = StopWatch.createStarted(); //创建后立即start,常用
        //StopWatch watch = new StopWatch();
        //watch.start();
        Thread.sleep(1000);
        System.out.println("统计从开始到现在运行时间:" + watch.getTime() + "ms"); //1000ms
        Thread.sleep(1000);
        watch.split();
        System.out.println("从start到此刻为止的时间:" + watch.getTime());
        System.out.println("从开始到第一个切入点运行时间:" + watch.getSplitTime()); //2245
        Thread.sleep(1000);
        watch.split();
        System.out.println("从开始到第二个切入点运行时间:" + watch.getSplitTime());
        watch.reset(); //重置后必须使用start方法
        watch.start();
        Thread.sleep(1000);
        System.out.println("重新开始后到当前运行时间是:" + watch.getTime()); //1000
        watch.suspend(); //暂停
        Thread.sleep(6000); //模拟暂停6秒钟
        watch.resume(); //上面suspend,这里要想重新统计,需要恢复一下
        System.out.println("恢复后执行的时间是:" + watch.getTime()); //1000  注意此时这个值还是1000
        watch.stop();
        System.out.println("花费的时间》》" + watch.getTime() + "ms"); //1002ms
        System.out.println("花费的时间》》" + watch.getTime(TimeUnit.SECONDS) + "s"); //1s 可以直接转成s
    }


打印结果:


统计从开始到现在运行时间:1007ms
从start到此刻为止的时间:2008
从开始到第一个切入点运行时间:2008
从开始到第二个切入点运行时间:3009
重新开始后到当前运行时间是:1000
恢复后执行的时间是:1000
花费的时间》》1001ms
花费的时间》》1s


如上就是StopWatch的基本使用方法,足以见到了它的强大吧,当然使用起来复杂度也是提升了些的。


核心原理解释


原理相对简单,简单看看源码便知:

// @since 2.0
public class StopWatch {
  // @since 3.5  这个静态方法出现得稍微晚点哦~
    public static StopWatch createStarted() {
        final StopWatch sw = new StopWatch();
        sw.start();
        return sw;
    }
  // 这些成员变量是实现的核心~~~~~~~~~~~~~~
    private State runningState = State.UNSTARTED;
    private SplitState splitState = SplitState.UNSPLIT;
    private long startTime;
  // 思考:为何有了nonaTime这里还得记录一个Millis Time呢???
  // 因为nanoTime只能拿来计算差值(耗时) 但是getStartTime()这个老API还得靠MillsTime~~~
    private long startTimeMillis;
    private long stopTime;
    // 可见:start方法可不是能够多次调用的哦~~和状态是有关的
    public void start() {
        if (this.runningState == State.STOPPED) {
            throw new IllegalStateException("Stopwatch must be reset before being restarted. ");
        }
        if (this.runningState != State.UNSTARTED) {
            throw new IllegalStateException("Stopwatch already started. ");
        }
        this.startTime = System.nanoTime();
        this.startTimeMillis = System.currentTimeMillis();
        this.runningState = State.RUNNING;
    }
  // 停表时,最重要的是记录下了stopTime 的值~~~然后标记状态
    public void stop() {
        if (this.runningState != State.RUNNING && this.runningState != State.SUSPENDED) {
            throw new IllegalStateException("Stopwatch is not running. ");
        }
        if (this.runningState == State.RUNNING) {
            this.stopTime = System.nanoTime();
        }
        this.runningState = State.STOPPED;
    }
  // 状态变为非开始状态...
    public void reset() {
        this.runningState = State.UNSTARTED;
        this.splitState = SplitState.UNSPLIT;
    }
  // 暂停:stopTime 也给了一个值
    public void suspend() {
        if (this.runningState != State.RUNNING) {
            throw new IllegalStateException("Stopwatch must be running to suspend. ");
        }
        this.stopTime = System.nanoTime();
        this.runningState = State.SUSPENDED;
    }
  // 这两个方法是获取差值的
    public long getTime() {
        return getNanoTime() / NANO_2_MILLIS;
    }
    // @since 3.5
    public long getTime(final TimeUnit timeUnit) {
        return timeUnit.convert(getNanoTime(), TimeUnit.NANOSECONDS);
    }
  // @since 2.4 老API  这叫获取启动的时间(啥时候启动的)
    public long getStartTime() {
        if (this.runningState == State.UNSTARTED) {
            throw new IllegalStateException("Stopwatch has not been started");
        }
        // System.nanoTime is for elapsed time
        return this.startTimeMillis;
    }
}


可以看到原理是很简单的,无非就是包装了暂停、回复、split等功能嘛

相关文章
|
2月前
|
消息中间件 监控 数据挖掘
基于RabbitMQ与Apache Flink构建实时分析系统
【8月更文第28天】本文将介绍如何利用RabbitMQ作为数据源,结合Apache Flink进行实时数据分析。我们将构建一个简单的实时分析系统,该系统能够接收来自不同来源的数据,对数据进行实时处理,并将结果输出到另一个队列或存储系统中。
108 2
|
21天前
|
存储 JSON 物联网
查询性能提升 10 倍、存储空间节省 65%,Apache Doris 半结构化数据分析方案及典型场景
本文我们将聚焦企业最普遍使用的 JSON 数据,分别介绍业界传统方案以及 Apache Doris 半结构化数据存储分析的三种方案,并通过图表直观展示这些方案的优势与不足。同时,结合具体应用场景,分享不同需求场景下的使用方式,帮助用户快速选择最合适的 JSON 数据存储及分析方案。
查询性能提升 10 倍、存储空间节省 65%,Apache Doris 半结构化数据分析方案及典型场景
|
9天前
|
IDE Java 分布式数据库
Apache HBase 落地JAVA 实战
Apache HBase 落地 Java 实战主要涉及使用 Java API 来操作 HBase 数据库,包括表的创建、删除、数据的插入、查询等操作。以下是一个基于 Java 的 HBase 实战指南,包括关键步骤和示例代码。
55 23
|
28天前
|
存储 大数据 数据挖掘
【数据新纪元】Apache Doris:重塑实时分析性能,解锁大数据处理新速度,引爆数据价值潜能!
【9月更文挑战第5天】Apache Doris以其卓越的性能、灵活的架构和高效的数据处理能力,正在重塑实时分析的性能极限,解锁大数据处理的新速度,引爆数据价值的无限潜能。在未来的发展中,我们有理由相信Apache Doris将继续引领数据处理的潮流,为企业提供更快速、更准确、更智能的数据洞察和决策支持。让我们携手并进,共同探索数据新纪元的无限可能!
78 11
|
2月前
|
人工智能 自然语言处理 Java
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
文章介绍了Spring AI,这是Spring团队开发的新组件,旨在为Java开发者提供易于集成的人工智能API,包括机器学习、自然语言处理和图像识别等功能,并通过实际代码示例展示了如何快速集成和使用这些AI技术。
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
|
2月前
|
消息中间件 Java Kafka
【Azure 事件中心】在微软云中国区 (Mooncake) 上实验以Apache Kafka协议方式发送/接受Event Hubs消息 (Java版)
【Azure 事件中心】在微软云中国区 (Mooncake) 上实验以Apache Kafka协议方式发送/接受Event Hubs消息 (Java版)
|
2月前
|
IDE Java 开发工具
快速上手指南:如何用Spring Boot开启你的Java开发之旅?
【8月更文挑战第22天】Spring Boot由Pivotal团队开发,简化了Spring应用的创建过程。本文详述了从零开始搭建Spring Boot项目的步骤:首先确保安装了新版JDK、Maven/Gradle及IDE如IntelliJ IDEA或Eclipse;接着访问Spring Initializr网站(start.spring.io),选择所需依赖(如Web模块)并生成项目;最后,使用IDE打开生成的项目,添加`@SpringBootApplication`注解及main方法来启动应用。通过这些步骤,即便是新手也能快速上手,专注于业务逻辑的实现。
34 1
|
2月前
|
消息中间件 Java Kafka
|
2月前
|
Java 持续交付 项目管理
Maven是一款基于Apache许可的项目管理和构建自动化工具,在Java开发中极为流行。
Maven是一款基于Apache许可的项目管理和构建自动化工具,在Java开发中极为流行。它采用项目对象模型(POM)来描述项目,简化构建流程。Maven提供依赖管理、标准构建生命周期、插件扩展等功能,支持多模块项目及版本控制。在Java Web开发中,Maven能够自动生成项目结构、管理依赖、自动化构建流程并运行多种插件任务,如代码质量检查和单元测试。遵循Maven的最佳实践,结合持续集成工具,可以显著提升开发效率和项目质量。
41 1
|
2月前
|
Java API 数据库
详细介绍如何使用Spring Boot简化Java Web开发过程。
Spring Boot简化Java Web开发,以轻量级、易用及高度可定制著称。通过预设模板和默认配置,开发者可迅速搭建Spring应用。本文通过创建RESTful API示例介绍其快速开发流程:从环境准备、代码编写到项目运行及集成数据库等技术,展现Spring Boot如何使Java Web开发变得更高效、简洁。
46 1

推荐镜像

更多
下一篇
无影云桌面