jsp中java代码无效_来杯咖啡,教你如何优雅的在java中统计代码块耗时
推薦閱讀:
Sping源碼+Redis+Nginx+MySQL等七篇實(shí)戰(zhàn)技術(shù)文檔,阿里大佬推薦
阿里內(nèi)部:2020年全技術(shù)棧文檔+PPT分享,(萬(wàn)粉總結(jié),回饋粉絲)
在我們的實(shí)際開(kāi)發(fā)中,多多少少會(huì)遇到統(tǒng)計(jì)一段代碼片段的耗時(shí)的情況,我們一般的寫(xiě)法如下
long start = System.currentTimeMillis();try { // .... 具體的代碼段} finally { System.out.println("cost: " + (System.currentTimeMillis() - start));}上面的寫(xiě)法沒(méi)有什么毛病,但是看起來(lái)就不太美觀了,那么有沒(méi)有什么更優(yōu)雅的寫(xiě)法呢?
1. 代理方式
了解 Spring AOP 的同學(xué)可能立馬會(huì)想到一個(gè)解決方法,如果想要統(tǒng)計(jì)某個(gè)方法耗時(shí),使用切面可以無(wú)侵入的實(shí)現(xiàn),如
// 定義切點(diǎn),攔截所有滿足條件的方法@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 的底層支持原理為代理模式,為目標(biāo)對(duì)象提供增強(qiáng)功能;在 Spring 的生態(tài)體系下,使用 aop 的方式來(lái)統(tǒng)計(jì)方法耗時(shí),可以說(shuō)少侵入且實(shí)現(xiàn)簡(jiǎn)單,但是有以下幾個(gè)問(wèn)題
- 統(tǒng)計(jì)粒度為方法級(jí)別
- 類(lèi)內(nèi)部方法調(diào)用無(wú)法生效(詳情可以參考博文:【SpringBoot 基礎(chǔ)系列教程】AOP 之高級(jí)使用技能)
2. AutoCloseable
在 JDK1.7 引入了一個(gè)新的接口AutoCloseable, 通常它的實(shí)現(xiàn)類(lèi)配合try{}使用,可在 IO 流的使用上,經(jīng)常可以看到下面這種寫(xiě)法
// 讀取文件內(nèi)容并輸出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();}注意上面的寫(xiě)法中,最值得關(guān)注一點(diǎn)是,不需要再主動(dòng)的寫(xiě)stream.close了,主要原因就是在try(){}執(zhí)行完畢之后,會(huì)調(diào)用方法AutoCloseable#close方法;
基于此,我們就會(huì)有一個(gè)大單的想法,下一個(gè)Cost類(lèi)實(shí)現(xiàn)AutoCloseable接口,創(chuàng)建時(shí)記錄一個(gè)時(shí)間,close 方法中記錄一個(gè)時(shí)間,并輸出時(shí)間差值;將需要統(tǒng)計(jì)耗時(shí)的邏輯放入try(){}代碼塊
下面是一個(gè)具體的實(shí)現(xiàn):
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-------");}執(zhí)行后輸出如下:
now 0now 1now 2now 3now 4cost: 55如果代碼塊拋異常,也會(huì)正常輸出耗時(shí)么?
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!"); } }}再次輸出如下,并沒(méi)有問(wèn)題
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. 小結(jié)
除了上面介紹的兩種方式,還有一種在業(yè)務(wù)開(kāi)發(fā)中不太常見(jiàn),但是在中間件、偏基礎(chǔ)服務(wù)的功能組件中可以看到,利用 Java Agent 探針技術(shù)來(lái)實(shí)現(xiàn),比如阿里的 arthas 就是在 JavaAgent 的基礎(chǔ)上做了各種上天的功能,后續(xù)介紹 java 探針技術(shù)時(shí)會(huì)專(zhuān)門(mén)介紹
下面小結(jié)一下三種統(tǒng)計(jì)耗時(shí)的方式
基本寫(xiě)法
long start = System.currentTimeMillis();try { // .... 具體的代碼段} finally { System.out.println("cost: " + (System.currentTimeMillis() - start));}優(yōu)點(diǎn)是簡(jiǎn)單,適用范圍廣泛;缺點(diǎn)是侵入性強(qiáng),大量的重復(fù)代碼
Spring AOP
在 Spring 生態(tài)下,可以借助 AOP 來(lái)攔截目標(biāo)方法,統(tǒng)計(jì)耗時(shí)
@Around("...")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); try{ return joinPoint.proceed(); } finally { System.out.println("cost: " + (System.currentTimeMillis() - start)); }}優(yōu)點(diǎn):無(wú)侵入,適合統(tǒng)一管理(比如測(cè)試環(huán)境輸出統(tǒng)計(jì)耗時(shí),生產(chǎn)環(huán)境不輸出);缺點(diǎn)是適用范圍小,且粒度為方法級(jí)別,并受限于 AOP 的使用范圍
AutoCloseable
這種方式可以看做是第一種寫(xiě)法的進(jìn)階版
// 定義類(lèi)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)); }}// 使用姿勢(shì)try (Cost c = new Cost()) { ...}優(yōu)點(diǎn)是:簡(jiǎn)單,適用范圍廣泛,且適合統(tǒng)一管理;缺點(diǎn)是依然有代碼侵入
說(shuō)明
上面第二種方法看著屬于最優(yōu)雅的方式,但是限制性強(qiáng);如果有更靈活的需求,建議考慮第三種寫(xiě)法,在代碼的簡(jiǎn)潔性和統(tǒng)一管理上都要優(yōu)雅很多,相比較第一種可以減少大量冗余代碼
作者:一灰灰
鏈接:https://juejin.im/post/5e5e4cc6518825493d6a96c4
總結(jié)
以上是生活随笔為你收集整理的jsp中java代码无效_来杯咖啡,教你如何优雅的在java中统计代码块耗时的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: bootstraptable 列隐藏_b
- 下一篇: sharpssh远程linux监控系统,