Java计时新姿势
为获得更好的阅读体验,请访问原文:传送门
前言: 最近公司来了个大佬,从他那里学到不少东西,其中一个就是计时
的新姿势「StopWatch」,赶紧来一起了解了解吧!

一、最简单的计时
在我们的程序中不免需要对某一个运算或者方法进行计时,以便我们来观察该运算或方法是否符合我们的预期,所以在我们刚开始接触 Java 的时候都能写出类似下面这样的代码来计时:
public static void main(String[] args) {
Long startTime = System.currentTimeMillis();
doSomeThing();
Long endTime = System.currentTimeMillis();
Long elapsedTime = (endTime - startTime) / 1000;
System.out.println("总共耗时:" + elapsedTime + "s");
}
// 用于模拟一些操作
private static void doSomeThing() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
事实上这样也并没有什么问题,并且也能够运行的很好,但是有一点不太好的就是,自己关注了太多输出的信息,下面我们来认识一种更优雅的一种计时方式;
二、StopWatch 类
想要使用它,首先你需要在你的 Maven 中引入 Spring 核心包,当然 Spring MVC 和 Spring Boot 都已经自动引入了该包:
<!-- spring核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
现在我们计时的姿势或许就会变成以下这样:
public static void main(String[] args) {
StopWatch clock = new StopWatch();
clock.start("开始任务一");
doSomeThing();
clock.stop();
clock.start("开始任务二");
doSomeThing();
clock.stop();
System.out.println(clock.prettyPrint());
}
// 用于模拟一些操作
private static void doSomeThing() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
在最后我们使用 StopWatch 类自带的 prettyPrint() 方法类格式化我们的输出,运行程序你会发现你的程序输出了这样的东西:
StopWatch '': running time (millis) = 2009
-----------------------------------------
ms % Task name
-----------------------------------------
01005 050% 开始任务一
01004 050% 开始任务二
不仅有总用时,还有每个任务分别的占用时间和占用时间的百分比,这或许就会比我们自己输出要优雅那么一些;
StopWatch 类是怎么实现的呢?
当你戳开 StopWatch 的源码,你会在总共不到 200 行的代码里看到熟悉的东西:
public void start(String taskName) throws IllegalStateException {
if (this.currentTaskName != null) {
throw new IllegalStateException("Can't start StopWatch: it's already running");
} else {
this.currentTaskName = taskName;
this.startTimeMillis = System.currentTimeMillis();
}
}
public void stop() throws IllegalStateException {
if (this.currentTaskName == null) {
throw new IllegalStateException("Can't stop StopWatch: it's not running");
} else {
long lastTime = System.currentTimeMillis() - this.startTimeMillis;
this.totalTimeMillis += lastTime;
this.lastTaskInfo = new StopWatch.TaskInfo(this.currentTaskName, lastTime);
if (this.keepTaskList) {
this.taskList.add(this.lastTaskInfo);
}
++this.taskCount;
this.currentTaskName = null;
}
}
你会发现该类使用 LinkedList 实现了一个叫做 taskList 的队列,然后每一次开始同样也是使用 System.currentTimeMillis() 方法来获取时间,每次除了计算耗时也会构建一个描述当前任务的 TaskInfo 对象,并把它放入 taskList 队列中。
当执行 prettyPrint() 方法的时候,就从 taskList 队列中依次取出任务,然后做些格式化的操作:
public String shortSummary() {
return "StopWatch '" + this.getId() + "': running time (millis) = " + this.getTotalTimeMillis();
}
public String prettyPrint() {
StringBuilder sb = new StringBuilder(this.shortSummary());
sb.append('\n');
if (!this.keepTaskList) {
sb.append("No task info kept");
} else {
sb.append("-----------------------------------------\n");
sb.append("ms % Task name\n");
sb.append("-----------------------------------------\n");
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMinimumIntegerDigits(5);
nf.setGroupingUsed(false);
NumberFormat pf = NumberFormat.getPercentInstance();
pf.setMinimumIntegerDigits(3);
pf.setGroupingUsed(false);
StopWatch.TaskInfo[] var4 = this.getTaskInfo();
int var5 = var4.length;
for(int var6 = 0; var6 < var5; ++var6) {
StopWatch.TaskInfo task = var4[var6];
sb.append(nf.format(task.getTimeMillis())).append(" ");
sb.append(pf.format(task.getTimeSeconds() / this.getTotalTimeSeconds())).append(" ");
sb.append(task.getTaskName()).append("\n");
}
}
return sb.toString();
}
摁,新姿势 get √。
按照惯例黏一个尾巴:
欢迎转载,转载请注明出处!
独立域名博客:wmyskxz.com
简书ID:@我没有三颗心脏
github:wmyskxz
欢迎关注公众微信号:wmyskxz
分享自己的学习 & 学习资料 & 生活
想要交流的朋友也可以加qq群:3382693
Java计时新姿势的更多相关文章
- Python一键转Jar包,Java调用Python新姿势!
粉丝朋友们,不知道大家看故事看腻了没(要是没腻可一定留言告诉我^_^),今天这篇文章换换口味,正经的来写写技术文.言归正传,咱们开始吧! 本文结构: 需求背景 进击的Python Java和Pytho ...
- Java 8新特性之旅:使用Stream API处理集合
在这篇“Java 8新特性教程”系列文章中,我们会深入解释,并通过代码来展示,如何通过流来遍历集合,如何从集合和数组来创建流,以及怎么聚合流的值. 在之前的文章“遍历.过滤.处理集合及使用Lambda ...
- 最通俗易懂的 Java 11 新特性讲解
大多数开发者还是沉浸在 Java 8 中,而 Java 14 将要在 2020 年 3 月 17 日发布了,而我还在写着 Java 11 的新特性.Java 11 是 Java 8 之后的第一个 LT ...
- Java 8新特性-4 方法引用
对于引用来说我们一般都是用在对象,而对象引用的特点是:不同的引用对象可以操作同一块内容! Java 8的方法引用定义了四种格式: 引用静态方法 ClassName :: staticMetho ...
- Java 8新特性终极指南
目录结构 介绍 Java语言的新特性 2.1 Lambdas表达式与Functional接口 2.2 接口的默认与静态方法 2.3 方法引用 2.4 重复注解 2.5 更好的类型推测机制 2.6 扩展 ...
- Spring 4支持的Java 8新特性一览
有众多新特性和函数库的Java 8发布之后,Spring 4.x已经支持其中的大部分.有些Java 8的新特性对Spring无影响,可以直接使用,但另有些新特性需要Spring的支持.本文将带您浏览S ...
- Atitit java jsp 新的tag技术
Atitit java jsp 新的tag技术 1.1. Tag Files vs 原生写 SimpleTag 比较麻烦的 JSP 1.x 允许 Web 开发人员创建 Java 组件(称为标记处 ...
- java 8 新特性
最近在IDEA的️驱使下,看了点java8的东西,链接贴一下,,,,, 1.Java 8新特性概述2.Java 8中的 Stream API 详解[3.Java 8新特性终极指南] 简单的使用看完新特 ...
- 【转+自己研究】新姿势之Docker Remote API未授权访问漏洞分析和利用
0x00 概述 最近提交了一些关于 docker remote api 未授权访问导致代码泄露.获取服务器root权限的漏洞,造成的影响都比较严重,比如 新姿势之获取果壳全站代码和多台机器root权限 ...
随机推荐
- 深入理解Java虚拟机(字节码执行引擎)
深入理解Java虚拟机(字节码执行引擎) 本文首发于微信公众号:BaronTalk 执行引擎是 Java 虚拟机最核心的组成部分之一.「虚拟机」是相对于「物理机」的概念,这两种机器都有代码执行的能力, ...
- jmeter模拟spike测试(尖峰测试)
概述 尖峰测试(Spike testing)在性能测试中属于压力测试的一个子集.指的是在某一瞬间或者多个频次下用户数和压力陡然增加的场景. 为了验证我们的网站在访问用户急剧增加的情况下,或者短时间内反 ...
- web页面加载速度缓慢,如何优化?
参考博客: https://www.cnblogs.com/xp796/p/5236945.html https://www.cnblogs.com/MarcoHan/p/5295398.html - ...
- mysql数据库在linux下的导出和导入及每天的备份
mysql数据库的导出,导入 1. 导出数据库为sql文件 mysqldump 数据库名 -uroot -p > xxx.sql 导出数据表结构和数据 eg. mysqldump cloud ...
- 长春理工大学第十四届程序设计竞赛(重现赛)J
J.Printout 题目:链接:https://ac.nowcoder.com/acm/contest/912/J 题目: 小r为了打校赛,他打算去打字社打印一份包含世界上所有算法的模板. 到了打字 ...
- springboot websocket集群(stomp协议)连接时候传递参数
最近在公司项目中接到个需求.就是后台跟前端浏览器要保持长连接,后台主动往前台推数据. 网上查了下,websocket stomp协议处理这个很简单.尤其是跟springboot 集成. 但是由于开始是 ...
- Appium+python自动化(十五)- Android 这些基础知识,你知多少???(超详解)
简介 前边具体操作和实战已经讲解和分享了很多了,但是一些android的一些基础知识,你又知道多少了,你都掌握了吗?这篇就由宏哥给小伙伴们既是一个分享,又是对前边的一次总结.为什么要对这些做一个简单的 ...
- HDU 4763:Theme Section(KMP)
http://acm.hdu.edu.cn/showproblem.php?pid=4763 Theme Section Problem Description It's time for mus ...
- 致远A8任意文件写入漏洞_getshell_exp
近期爆出致远 OA 系统的一些版本存在任意文件写入漏洞,远程攻击者在无需登录的情况下可通过向 URL /seeyon/htmlofficeservlet POST 精心构造的数据即可向目标服务器写入任 ...
- 【深入浅出-JVM】(34):CMS 回收器
概念 Concurrent Mark Sweep 并发标记清除(多线程并且用的标记清除算法),会造成大量的内存碎片,离散的可用空间无法分配较大的对象 流程 参数 -XX:-CMSPrecleaning ...