jsp中java代码无效_来杯咖啡,教你如何优雅的在java中统计代码块耗时

推荐阅读:

Sping源码+Redis+Nginx+MySQL等七篇实战技术文档,阿里大佬推荐

阿里内部:2020年全技术栈文档+PPT分享,(万粉总结,回馈粉丝)

1e0264bc6a52929e72f946c03636eb9f.png

在我们的实际开发中,多多少少会遇到统计一段代码片段的耗时的情况,我们一般的写法如下

long start = System.currentTimeMillis();try {    // .... 具体的代码段} finally {    System.out.println("cost: " + (System.currentTimeMillis() - start));}

上面的写法没有什么毛病,但是看起来就不太美观了,那么有没有什么更优雅的写法呢?

1. 代理方式

了解 Spring AOP 的同学可能立马会想到一个解决方法,如果想要统计某个方法耗时,使用切面可以无侵入的实现,如

// 定义切点,拦截所有满足条件的方法@Pointcut("execution(public * com.git.hui.boot.aop.demo.*.*(*))")public void point() {}@Around("point()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {    long start = System.currentTimeMillis();    try{        return joinPoint.proceed();    } finally {        System.out.println("cost: " + (System.currentTimeMillis() - start));    }}

Spring AOP 的底层支持原理为代理模式,为目标对象提供增强功能;在 Spring 的生态体系下,使用 aop 的方式来统计方法耗时,可以说少侵入且实现简单,但是有以下几个问题

  • 统计粒度为方法级别
  • 类内部方法调用无法生效(详情可以参考博文:【SpringBoot 基础系列教程】AOP 之高级使用技能)

2. AutoCloseable

在 JDK1.7 引入了一个新的接口AutoCloseable, 通常它的实现类配合try{}使用,可在 IO 流的使用上,经常可以看到下面这种写法

// 读取文件内容并输出try (Reader stream = new BufferedReader(new InputStreamReader(new FileInputStream("/tmp")))) {    List list = ((BufferedReader) stream).lines().collect(Collectors.toList());    System.out.println(list);} catch (IOException e) {    e.printStackTrace();}

注意上面的写法中,最值得关注一点是,不需要再主动的写stream.close了,主要原因就是在try(){}执行完毕之后,会调用方法AutoCloseable#close方法;

基于此,我们就会有一个大单的想法,下一个Cost类实现AutoCloseable接口,创建时记录一个时间,close 方法中记录一个时间,并输出时间差值;将需要统计耗时的逻辑放入try(){}代码块

下面是一个具体的实现:

public static class Cost implements AutoCloseable {    private long start;    public Cost() {        this.start = System.currentTimeMillis();    }    @Override    public void close() {        System.out.println("cost: " + (System.currentTimeMillis() - start));    }}public static void testPrint() {    for (int i = 0; i < 5; i++) {        System.out.println("now " + i);        try {            Thread.sleep(10);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}public static void main(String[] args) {    try (Cost c = new Cost()) {        testPrint();    }    System.out.println("------over-------");}

执行后输出如下:

now 0now 1now 2now 3now 4cost: 55

如果代码块抛异常,也会正常输出耗时么?

public static void testPrint() {    for (int i = 0; i < 5; i++) {        System.out.println("now " + i);        try {            Thread.sleep(10);        } catch (InterruptedException e) {            e.printStackTrace();        }        if (i == 3) {            throw new RuntimeException("some exception!");        }    }}

再次输出如下,并没有问题

now 0now 1now 2now 3cost: 46Exception in thread "main" java.lang.RuntimeException: some exception!at com.git.hui.boot.order.Application.testPrint(Application.java:43)at com.git.hui.boot.order.Application.main(Application.java:50)

3. 小结

除了上面介绍的两种方式,还有一种在业务开发中不太常见,但是在中间件、偏基础服务的功能组件中可以看到,利用 Java Agent 探针技术来实现,比如阿里的 arthas 就是在 JavaAgent 的基础上做了各种上天的功能,后续介绍 java 探针技术时会专门介绍

下面小结一下三种统计耗时的方式

基本写法

long start = System.currentTimeMillis();try {    // .... 具体的代码段} finally {    System.out.println("cost: " + (System.currentTimeMillis() - start));}

优点是简单,适用范围广泛;缺点是侵入性强,大量的重复代码

Spring AOP

在 Spring 生态下,可以借助 AOP 来拦截目标方法,统计耗时

@Around("...")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {    long start = System.currentTimeMillis();    try{        return joinPoint.proceed();    } finally {        System.out.println("cost: " + (System.currentTimeMillis() - start));    }}

优点:无侵入,适合统一管理(比如测试环境输出统计耗时,生产环境不输出);缺点是适用范围小,且粒度为方法级别,并受限于 AOP 的使用范围

AutoCloseable

这种方式可以看做是第一种写法的进阶版

// 定义类public static class Cost implements AutoCloseable {    private long start;    public Cost() {        this.start = System.currentTimeMillis();    }    @Override    public void close() {        System.out.println("cost: " + (System.currentTimeMillis() - start));    }}// 使用姿势try (Cost c = new Cost()) {    ...}

优点是:简单,适用范围广泛,且适合统一管理;缺点是依然有代码侵入

说明

上面第二种方法看着属于最优雅的方式,但是限制性强;如果有更灵活的需求,建议考虑第三种写法,在代码的简洁性和统一管理上都要优雅很多,相比较第一种可以减少大量冗余代码


作者:一灰灰
链接:https://juejin.im/post/5e5e4cc6518825493d6a96c4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/561005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 随机抽取文件,shell 随机从文件中抽取若干行的实现方法

shuf -n5 main.txtsort -R main.txt | head -5awk -vN5 -vC"wc -l file" BEGIN{srand();while(nwhile read line;do echo "$line $RANDOM";done < main.txt | sort -k2,2n| awk NR<5{print $1}shuf 命令的选项&#xff1a;-e, --echo &#xff1a;将…

http header 设置编码_【译】http.client

本模块实现了HTTP和HTTPS协议的客户端功能。通常本模块不会被直接使用&#xff0c;而是被urllib.request调用&#xff0c;来处理HTTP和HTTPS相关的URL。备注&#xff1a;HTTPS只有在支持SSL(带有ssl模块)的Python编译器里面才是可用的。(一)模块提供的类class http.client.HTTP…

diskgenius linux 分区,DiskGenius怎么分区,DiskGenius分区教程

DiskGenius分区教程方法一&#xff1a;一、首先&#xff0c;打开DiskGenius软件并单击以选择要操作的硬盘驱动器。二、然后右键单击“快速分区”按钮并单击“确定”。方法2&#xff1a;三、选择要操作的硬盘&#xff0c;单击软件上方的硬盘按钮&#xff0c;单击下面列中的快速分…

sql server management studio性能分析_如何分析一条SQL的性能

来自公众号&#xff1a;谭小谭这篇文章将给大家介绍如何使用 explain 来分析一条 sql 。网上其实已经有非常多的文章都很详细的介绍了 explain 的使用&#xff0c;这篇文章将实例和原理结合起来&#xff0c;尽量让你有更好的理解&#xff0c;相信我&#xff0c;认真看完你应该会…

编译运行linux0.12,linux0.12 编译过程

感谢这篇文章的作者&#xff1a; http://www.cnblogs.com/strugglesometimes/p/4231359.html编译是个很蛋疼的事情&#xff0c;本想把linux0.12在bochs上跑起来然后就可以各模块的学习&#xff0c;没想各种问题。问题1&#xff1a;1 gas -c -o boot/head.o boot/head.s2 mak…

编译linux tq2440,QT4.8.2在TQ2440开发板上的移植(一)--编译和安装

主机版本&#xff1a;Ubuntu 11.04交叉编译器版本&#xff1a;4.3.3移植的主要工作就是编译在ARM板上运行的qt库&#xff0c;并且把这些库做到根目录中。需要的文件tslib-1.4.tar.gz qt-everywhere-opensource-src-4.8.2.tar.gz具体步骤如下&#xff1a;1、首先编译安装触摸屏驱…

图书管理系统_目前图书管理系统存在的问题

作者&#xff1a;新风学术网(一) 不能准确直观地指明图书所在的空间位置目前所使用的管理系统在索书的过程中是读者先在图书馆查询系统上查询到所要借的图书并记录下这本书的索书号和馆藏地, 再根据索书号到书的馆藏地所在位置查找书。有些读者对索书号是怎么排架的并不了解, 也…

(dp)数字三角形

题目方案1&#xff1a;递归方案二&#xff1a;递推 题目 数字三角形问题。有一个由非负整数组成的三角形&#xff0c;第一行只有一个数&#xff0c;除了最下行 之外每个数的左下方和右下方各有一个数 从第一行的数开始&#xff0c;每次可以往左下或右下走一格&#xff0c;直…

mfc tabcontrol 修改白色背景_初级会计报名准备工作如何使用美图秀秀PC版修改照片尺寸、格式、大小...

点击上方蓝字关注我们证件照是我们生活中常用的东西&#xff0c;大学考证需要证件照&#xff0c;制作简历也需要用到证件照&#xff0c;工作有时也需要用到&#xff0c;然而最让我们头疼的是每次报名证件照的要求都不一样&#xff0c;其中底色和尺寸是经常需要修改的&#xff0…

分步表单_表单设计-掌握表单设计方法(表单体验篇)

全篇阅读大概需要15min&#xff0c;对表单设计不熟悉的同学看完后肯定会有不少的收获~~~说到表单其实在生活中可以接触到各种各样的表单&#xff0c;比如&#xff1a;驾照申请表、体检表、银行开户需要填写的表等等&#xff0c;这些都是表单&#xff0c;主要目的就是让用户填写…

4)lsof linux命令,***Linux命令实时监测系统(top,htop,iotop,lsof,tcpdump,netstat,vmstat,iostat)...

摘要&#xff1a;本文总结了8个非常实用的Linux命令行性能监测工具&#xff0c;这些命令支持所有的Linux系统&#xff0c;不仅可以用于监控系统&#xff0c;还可以发现导致性能问题的原因所在。对每个系统/网络管理员来说&#xff0c;每天监测Linux系统性能是一项非常艰巨的任务…

算法竞赛入门经典 第七章 总结

目录&#xff1a; 7.1 简单枚举7.2 枚举排列7.3 子集生成 7.1 简单枚举 例题7-1 除法&#xff08;Division, UVa 725&#xff09; 输入正整数n&#xff0c;按从小到大的顺序输出所有形如abcde/fghij n的表达式&#xff0c;其中a&#xff5e;j恰好 为数字0&#xff5e…

线性表总结

线性表及其实现多项式的表示什么是线性表线性表的抽象数据类型描述线性表的顺序存储实现线性表的链式存储实现 线性表及其实现 多项式的表示 [例] 一元多项式及其运算 一元多项式 &#xff1a; 主要运算&#xff1a;多项式相加、相减、相乘等 【分析】如何表示多项式?…

mix2s android p功能,已升安卓P!网友:MIX2S才是亲儿子

原标题&#xff1a;已升安卓P&#xff01;网友&#xff1a;MIX2S才是亲儿子一直以来&#xff0c;小米在手机系统更新上都有着非常明显的优势&#xff0c;MIUI经过了多年的更新迭代&#xff0c;如今已经达到了非常不错的易用性&#xff0c;而且流畅度方面的表现更是优秀。如今小…

堆栈总结

堆栈什么是堆栈堆栈的抽象数据类型描述栈的顺序存储实现 堆栈 什么是堆栈 计算机如何进行表达式求值&#xff1f; 算术表达式56/2-3*4。 正确理解&#xff1a; 56/2-3*4 53-3*4 8-3*4 8-12 -4 由两类对象构成的&#xff1a; 运算数&#xff0c;如2、3、4 运算符号…

harmonyos公测招募,nova为主 HarmonyOS 2.0开发者Beta公测再招募

原标题&#xff1a;nova为主 HarmonyOS 2.0开发者Beta公测再招募HarmonyOS 2.0开发者Beta公测招募将开启第二期&#xff0c;本次公测活动主要针对的机型是华为nova系列。活动报名时间为5月9日-5月17日。【PChome手机频道资讯报道】华为方面在4月份开启了HarmonyOS 2.0开发者Bet…

队列总结

什么是队列 队列(Queue)&#xff1a;具有一定操作约束的线性表 插入和删除操作&#xff1a;只能在一端插入&#xff0c;而在另一端删除 数据插入&#xff1a;入队列&#xff08;AddQ&#xff09; 数据删除&#xff1a;出队列&#xff08;DeleteQ&#xff09; 先来先服务 先…

D P- 免费馅饼

题目 都说天上不会掉馅饼&#xff0c;但有一天gameboy正走在回家的小径上&#xff0c;忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了&#xff0c;这馅饼别处都不掉&#xff0c;就掉落在他身旁的10米范围内。馅饼如果掉在了地上当然就不能吃了&#xff0c;所以ga…

一加桌面3.0 android8,一加手机XRemix6.0安卓8.1.0Beta2.0定制本地化增强适配归属农历等...

制作者&#xff1a;moonlight-roms基于版本&#xff1a;remix最新安卓8.1.0代码适合机型&#xff1a;一加手机X双网版/全网通版/E1001/E1003等/onyx注意事项&#xff1a;1.开机后语言设置&#xff1a;Settings-system-languageandinput-添加一个中文需要并拖动到第一行设置为默…

震惊!Fibonacci Again

题目 There are another kind of Fibonacci numbers: F(0) 7, F(1) 11, F(n) F(n-1) F(n-2) (n>2). Input Input consists of a sequence of lines, each containing an integer n. (n < 1,000,000). Output Print the word “yes” if 3 divide evenly into …