定时器可以用在很多地方。本文主要介绍Java定时器工具秒表的具体使用。通过示例代码进行了非常详细的介绍,对大家的学习或工作有一定的参考价值。让我们和边肖一起学习。
目录
前言弹簧秒表练习示例源代码分析lang3秒表总结
前言
通常我们要统计某个代码块或者某个方法的执行时间。最简单的方法如下。
包com.chenpi
/**
* @作者陈皮
* @版本1.0
* @描述
* @日期2022年4月2日
*/
公共类陈皮{
公共静态void main(String[] args)引发InterruptedException {
long start time=system . current time millis();
thread . sleep(1000);
long end time=system . current time millis();
System.out.println('执行时间(毫秒):'(end Time-start Time));
}
}
//输出结果如下
执行时间(毫秒):1011
但是如果要对多个代码段进行计时,每个阶段计时的比例,如果还是采用上面的方法,那么与业务无关的代码会比较多,不够简洁。
Spring StopWatch
Spring框架有一个工具类秒表,可以用来对程序中的代码块或方法进行计时,支持多阶段计时,统计如阶段时间的比例等。代码简洁且易于使用。
包com.chenpi
导入org . spring framework . util . stopwatch;
/**
* @作者陈皮
* @版本1.0
* @描述
* @日期2022年4月2日
*/
公共类陈皮{
公共静态void main(String[] args)引发InterruptedException {
//声明一个计时器
秒表秒表=新秒表('陈皮计时器');
//开始计时
StopWatch.start(“发送MQ计时”);
thread . sleep(1000);
//结束计时
秒表. stop();
//打印统计数据
system . out . println(stopwatch . pretty print());
}
}
//输出结果如下
秒表“陈皮计时器”:运行时间=1005775500 ns
-
ns %任务名称
-
1005775500 100%发送MQ计时
弹簧秒表有以下几种常用方法:
StopWatch():构造一个计时器秒表(字符串id):用指定的id构造一个计时器。
Start():创建一个名为空字符串的定时任务并开始计时。start(String taskName):创建一个具有指定名称和开始计时的定时任务。stop():结束当前任务的计时。getTotalTimeNanos():获取所有任务的执行时间。纳秒getTotalTimeMillis():获取所有任务的执行时间,毫秒shortSummary():获取简单的统计信息prettyPrint():以友好的方式输出总的统计时间,以及各阶段任务的执行时间。SetKeepTasklist(Boolean keep task List):是否将每个任务存储在内部列表中?
实践例子
当程序中有多个定时器时,可以通过构造不同id的定时器来区分。下面演示几种不同的定时器,统计不同阶段的执行时间。
包com.chenpi
导入org . spring framework . util . stopwatch;
/**
* @作者陈皮
* @版本1.0
* @描述
* @日期2022年4月2日
*/
公共类陈皮{
公共静态void main(String[] args)引发InterruptedException {
m1();
m2();
}
私有静态void m1()引发InterruptedException {
//声明一个计时器
秒表秒表=新秒表(“M1计时器”);
StopWatch.start('查询数据库');
thread . sleep(1000);
秒表. stop();
StopWatch.start(“逻辑计算”);
thread . sleep(500);
秒表. stop();
system . out . println(stopwatch . pretty print());
}
私有静态void m2()引发InterruptedException {
//声明一个计时器
秒表秒表=新秒表(“m2计时器”);
秒表。开始('远程调用');
线程。睡眠(800);
秒表。stop();
秒表。开始('发送MQ’);
线程。睡眠(200);
秒表。stop();
系统。出去。println(秒表。蛮印());
}
}
//输出结果如下
秒表货币供应量计时器:运行时间=1516953200纳秒
-
ns %任务名称
-
1008091000 066% 查询数据库
508862200 034% 逻辑计算
秒表货币供应量之二计时器:运行时间=1013080000纳秒
-
ns %任务名称
-
809345900 080% 远程调用
203734100 020% 发生(法属)马提尼克岛(马提尼克岛的简写)
源码分析
其实跑表底层实现很简单,对于每一个任务,在任务开始和结束时刻调用系统. nanoTime* ()方法获取服务器当前的时间,然后计算每一个任务的执行时间,存储在内部。内部使用一个列表存储不同任务阶段的执行时间,最后打印输出。
包org。spring框架。util
导入Java。文字。数字格式;
导入Java。util。ArrayList
导入Java。util。列表;
导入Java。util。并发。时间单位;
导入org。spring框架。郎。可空;
公共类秒表{
//计时器身份证明(识别)
私有最终字符串id;
//是否将任务存储到任务列表中
private boolean keepTaskList=true;
//存储全部任务的列表
private final listaskinfo任务列表=new ArrayList(1);
//当前任务开始时间
私有长启动时间毫微秒
//当前任务名称
@Nullable
私有字符串当前任务名称
//最后一个任务
@Nullable
private TaskInfo lastTaskInfo
//总任务数
私有int任务计数
//总的执行时间
私有long totalTimeNanos
//构造一个身份证明(识别)为空字符串的计时器
公共秒表(){
这个("");
}
//构造一个指定身份证明(识别)的计时器
公共秒表(字符串id) {
this.id=id
}
//获取计时器身份证明(识别)
公共字符串getId() {
返回this.id
}
public void setKeepTaskList(boolean keepTaskList){
这个。keepTaskList=keepTaskList
}
//开始计时
公共无效开始()引发IllegalStateException {
开始("");
}
//开始一个指定任务名称的计时
公共void start(字符串任务名)引发IllegalStateException {
if (this.currentTaskName!=null) {
抛出新的IllegalStateException(“无法启动秒表:它已经在运行');
}
this.currentTaskName=taskName
这个。starttimenanos=系统。纳米时间();
}
//停止任务计时
公共无效停止()引发了IllegalStateException {
如果(这个。当前任务名称==null){
抛出新的IllegalStateException(“无法停止秒表:它没有运行');
}
持续时间长=系统。纳米时间()-这个。starttimenanos
this.totalTimeNanos=lastTime
这个。上次任务信息=新任务信息(this。当前taskname,上次);
if (this.keepTaskList) {
这个。任务列表。补充(这个。lastaskinfo);
}
这个。任务计数;
这个。当前任务名称=null
}
public boolean isRunning() {
return (this.currentTaskName!=null);
}
@Nullable
公共字符串currentTaskName() {
返回this.currentTaskName
}
公共long getLastTaskTimeNanos()抛出IllegalStateException {
如果(这个。lastaskinfo==null){
抛出新的IllegalStateException(“没有任务运行:无法获取最后一个任务间隔');
}
返回这个。lastaskinfo。gettimenanos();
}
公共long getLastTaskTimeMillis()抛出IllegalStateException {
如果(这个。lastaskinfo==null){
抛出新的IllegalStateException(“没有任务运行:无法获取最后一个任务间隔');
}
返回这个。lastaskinfo。gettimemillis();
}
公共字符串getLastTaskName()引发IllegalStateException {
如果(这个。lastaskinfo==null){
抛出新的IllegalStateException(“没有任务运行:无法获取最后一个任务名');
}
返回这个。lastaskinfo。gettaskname();
}
public TaskInfo getLastTaskInfo()抛出IllegalStateException {
如果(这个。lastaskinfo==null){
抛出新的IllegalStateException('没有任务运行:无法获取上一个任务信息');
}
返回this.lastTaskInfo
}
public long getTotalTimeNanos() {
返回this.totalTimeNanos
}
public long getTotalTimeMillis(){
返回nanosToMillis(这个。totaltimenanos);
}
public double getTotalTimeSeconds(){
返回毫微秒(这个。totaltimenanos);
}
public int getTaskCount() {
返回这个。任务计数;
}
public TaskInfo[] getTaskInfo() {
如果(!this.keepTaskList) {
抛出新的UnsupportedOperationException(“没有保留任务信息!");
}
返回这个。任务列表。to数组(新任务信息[0]);
}
公共字符串shortSummary() {
返回“秒表' ' getId()' ':运行时间=' gettotal menanos()' ns ';
}
公共字符串prettyPrint() {
StringBuilder sb=new StringBuilder(short summary());
某人(somebody的简写)追加(' \ n ');
如果(!this.keepTaskList) {
某人追加('不保留任务信息');
}
否则{
某人(somebody的简写)追加('-\ n ');
某人(somebody的简写)append(' ns %任务名\ n ');
某人(somebody的简写)追加('-\ n ');
数字格式nf=数字格式。获取number实例();
nf。setminimumintegerdigits(9);
nf。setgroupingused(false);
数字格式pf=数字格式。getpercentinstance();
pf。setminimumintegerdigits(3);
pf。setgroupingused(false);
for(TaskInfo task:getTaskInfo()){
某人(somebody的简写)追加(nf。格式(任务。gettimenanos()).追加("");
某人(somebody的简写)追加(pf。格式((双)任务。getti menanos()/gettotal menanos()).追加("");
sb.append(task.getTaskName()).追加(' \ n ');
}
}
归还某人。tostring();
}
@覆盖
公共字符串toString() {
StringBuilder sb=new StringBuilder(short summary());
if (this.keepTaskList) {
for(TaskInfo task:getTaskInfo()){
某人追加(';[').append(task.getTaskName()).追加(']take ').append(task.getTimeNanos()).append(' ns ');
长百分比=数学。round(100.0 *任务。getti menanos()/gettotal menanos());
某人追加('=').追加(百分比)。追加("%");
}
}
否则{
某人追加(';没有保存任务信息'));
}
归还某人。tostring();
}
私有静态长纳米隧道(长持续时间){
返回时间单位。纳秒。托米利斯(持续时间);
}
私有静态双纳秒(长持续时间){
返回持续时间/1 _ 000 _ 000 _ 000.0;
}
//任务实体
公共静态最终类TaskInfo {
//任务名称
私有最终字符串任务名
//任务执行时间
私人最终长期纳米;
TaskInfo(String taskName,long timeNanos) {
this.taskName=任务名
这个。时间毫微秒=时间毫微秒;
}
公共字符串getTaskName() {
返回这个. taskName
}
public long getTimeNanos() {
返回这个。时间纳米;
}
public long getTimeMillis() {
返回nanosToMillis(这个。时间毫微秒);
}
public double getTimeSeconds() {
返回毫微秒(这个。时间毫微秒);
}
}
}
复制代码
跑表使用起来简洁,支持多任务阶段统计,统计多任务时间占比等,统计结果直观。但是它也有不好的地方,就是一个跑表实例只能同时开始一个任务,只能等这个工作进行停止之后,才能继续开始另一个任务。注意,秒表实例不是线程安全的,也没必要进行同步处理。
lang3 StopWatch
Apache commons语言3包下也有一个用于计时工具类秒表。它还有暂停计时,恢复计时,设置分割点等功能。
nbsporg。阿帕奇。公地:公地-朗3:3。12 .0
复制代码
它主要有以下几个常用方法:
创建():实例化一个计时器createStarted():实例化一个计时器,并开始计时秒表(最终字符串消息):实例化一个带有标识符的计时器
start():开始计时拆分():设置分割点getSplitTime():统计从开始开始最后一个分割点的用时重置():重置计时挂起():暂停计时简历():恢复计时停止():停止计时getTime():统计从开始到当前时刻的同时
包com.chenpi
导入org。阿帕奇。公地。郎3。时间。秒表;
/**
* @作者陈皮
* @版本1.0
* @描述
* @日期2022年四月2日
*/
公共类陈皮{
公共静态void main(String[] args)引发中断的异常{
//声明一个计时器
秒表秒表=新秒表(' m1计时器');
秒表。start();
thread . sleep(1000);
System.out.println('开始时间至今:' stopwatch . gettime());
stopwatch . split();
thread . sleep(500);
system . out . println(' start from start to last split:' stopwatch . getsplittime());
stopwatch . split();
thread . sleep(500);
system . out . println(' start from start to last split:' stopwatch . getsplittime());
//重置计时
秒表. reset();
线程.睡眠(2000年);
秒表. start();
thread . sleep(1000);
System.out.println('开始时间至今:' stopwatch . gettime());
//暂停计时
秒表. suspend();
thread . sleep(3000);
//恢复计时
秒表. resume();
thread . sleep(1000);
//结束计时
秒表. stop();
thread . sleep(1000);
System.out.println('开始时间到停止时间:' stopwatch . gettime());
System.out.println(秒表);
}
}
//输出结果如下
从开始到现在的时间:1000
从开始到最后一次分割的时间:1001
从开始到最后一次分割的时间:1510
从开始到现在的时间:1004
起止时间:2015年
M1计时器00:00:02.015
总结
如果是简单的计算和执行计时,可以使用JDK自己的类来获取系统时间进行计时。如果需要多阶段计时,需要统计各阶段的执行时间比例等信息,可以使用秒表工具类。推荐Spring秒表,因为我们项目本身用的Spring框架比较多,自带秒表。
关于Java计时器工具秒表的具体使用,本文到此结束。有关Java计时器工具秒表的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。