转载请注明出处::https://blog.csdn.net/jevonsCSDN/article/details/83118799 【Jevons’Blog】
本文是关于实时监控方法耗时的工具,不依赖任何插件,丢进去就可以用。本工具类采用ThreadLocal实现多线程分化管理监控信息,不用担心结果的准确性。写的比较潦草,由于本人只是用于测试,懒得优化了,有兴趣的可以改改。
方便用于测试,不建议投入生产。

import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
/*** 耗时监控类(测试用,不建议在生产环境跑)* 严格按照每个start方法由一个end方法结束(缺失end块会导致内存泄漏)* @author Zhang Haowen*/
public class CostMonitorUtils {private static final Map<PatternType, Vector<SimpleDateFormatSub>> TYPE_MAP = new HashMap<PatternType, Vector<SimpleDateFormatSub>>(); private static final int maxSize = 0x32;//格式池最大值:50private static boolean outputTolog                = true;//[true]:日志打印到文件|[false]:日志不打印到文件private static String  currentDate               = new SimpleDateFormat("yyyyMMdd").format(new Date());private static final String LOG_PATH           = "E:\\CostMonitor";static {for(PatternType patternType: PatternType.values()){TYPE_MAP.put(patternType, new Vector<SimpleDateFormatSub>());}}//耗时记录器private static ThreadLocal<List<Long>> timeMillsRecord = new ThreadLocal<List<Long>>(){@Overrideprotected List<Long> initialValue() {return new ArrayList<Long>();};};//监控文件名、行号记录器private static ThreadLocal<List<String>> lineRecord = new ThreadLocal<List<String>>(){@Overrideprotected List<String> initialValue() {return new ArrayList<String>();};};private static Long start(String message,String endLineInfo){SimpleDateFormatSub formator = getFormator(PatternType.YEAR_TO_SECOND);String finalMessage="";message=rebuildMessage(message);long startTimeMillis = System.currentTimeMillis();//记录开始监控时间List<Long> list = timeMillsRecord.get();list.add(startTimeMillis);//记录开始监控文件名、行数List<String> lineRecordList = lineRecord.get();lineRecordList.add(endLineInfo);if(!message.equals("")){endLineInfo= rebuildMessage(endLineInfo);finalMessage=">>>>"+message+endLineInfo+"开始耗时监控---> "+ formator.format(new Date());System.out.println(finalMessage);}free(formator);outputToLogFile(finalMessage+"\r\n");return startTimeMillis;}/*** 开始监控* @param message* @return*/public static Long start(String message){return start(message,getLineInfo(2));}/*** 调整message格式* @param message* @return*/private static String rebuildMessage(String message){if(message!=null&&!message.equals("")){message =" "+message+" ";}else{message ="";}return message;}/*** 开始耗时监控* @return 返回开始时间戳*/public static Long start(){return start(null,getLineInfo(2));}/*** 结束耗时监控* @return 返回结束时间戳*/public static Long end(){return end(null,getLineInfo(2));}/*** 结束耗时监控* @param message* @return*/public static Long end(String message) {return end(message, getLineInfo(2));}/*** 结束耗时监控* @param message* @return  返回结束时间戳* @throws Exception */private static Long end(String message,String endLineInfo){String finalMessage="";message=rebuildMessage(message);long endTimeMillis  = System.currentTimeMillis();List<Long> list = timeMillsRecord.get();List<String> lineRecordList = lineRecord.get();if(list.size()>0){Long startTimeMillis = list.remove(list.size()-1);String lineInfo = rebuildMessage(lineRecordList.remove(lineRecordList.size()-1)+" → "+endLineInfo);//格式化毫秒String costTime =formatMS(endTimeMillis-startTimeMillis,false);finalMessage=">>>>"+lineInfo+"Cost Time:"+costTime+message;System.out.println(finalMessage);}else{clearCache();finalMessage="The CostMonitor hasn't started yet.";System.out.println(finalMessage);}outputToLogFile(finalMessage+"\r\n");return endTimeMillis;}/*** 获取行号信息* @param index* @return*/public static String getLineInfo(int index) {StackTraceElement ste3 = new Throwable().getStackTrace()[index];return (ste3.getFileName() + ": Line " + ste3.getLineNumber());}/*** 输出到日志文件* @param value* @throws IOException*/private static void outputToLogFile(String value) {if(!outputTolog){return ;}if(value==null||value.trim().equals("")) return ;FileOutputStream out = null;try {out = new FileOutputStream(LOG_PATH+currentDate+".log",true);out.write(value.getBytes("UTF-8"));} catch (Exception e) {e.printStackTrace();} finally{try {out.flush();out.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}/*** 清除缓存* @throws Exception */public static void clearCache(){if(timeMillsRecord.get()!=null&&timeMillsRecord.get().size()!=0){outputToLogFile("CostMonitorUtils tried to clear cache denied!One or more START block is not ended!\r\n");return ;}timeMillsRecord.remove();lineRecord.remove();}/*** 将毫秒转为时分秒格式* @param millisecond* @param chinese 是否启用中文* @return*/private static String formatMS(long millisecond,boolean chinese){String h     = chinese?"小时":"h";String m    = chinese?"分":"m";String s     = chinese?"秒":"s";String ms    = chinese?"毫秒":"ms";if(millisecond>=3600000){return millisecond/3600000+h+(millisecond%3600000)/60000+m+(millisecond%60000)/1000+s+(millisecond%1000)+ms;}else if(millisecond>=60000&&millisecond<3600000){return millisecond/60000+m+(millisecond%60000)/1000+s+(millisecond%1000)+ms;}else if(millisecond>=1000&&millisecond<60000){return millisecond/1000+s+ (millisecond%1000)+ms;}else{return millisecond+ms;}}public static synchronized SimpleDateFormatSub getFormator(PatternType patternType){if(TYPE_MAP.get(patternType).size()==0){return new SimpleDateFormatSub(patternType);}else{return TYPE_MAP.get(patternType).remove(0);}}public static synchronized SimpleDateFormatSub getFormator(){return getFormator(PatternType.values()[0]);//default}public static synchronized void free(SimpleDateFormatSub sdf){if(TYPE_MAP.get(sdf.getPatternType()).size()<maxSize){TYPE_MAP.get(sdf.getPatternType()).add(sdf);}}public static class SimpleDateFormatSub extends SimpleDateFormat{private static final long serialVersionUID = 1L;private PatternType patternType;public SimpleDateFormatSub(PatternType patternType) {super.applyPattern(patternType.toString());;this.setPatternType(patternType);}public PatternType getPatternType() {return patternType;}public void setPatternType(PatternType patternType) {this.patternType = patternType;}}public enum PatternType{YEAR_TO_DAY ("yyyy-MM-dd"),YEAR_TO_SECOND ("yyyy-MM-dd HH:mm:ss");private String patternValue;private PatternType(String patternValue) {this.patternValue=patternValue;}@Overridepublic String toString() {return this.patternValue;}}public static void main(String[] args) {for (int i = 0; i < 1000; i++) {new Thread( new Runnable() {public void run() {CostMonitorUtils.start();try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}CostMonitorUtils.end();}}).start();}}}

CostMonitorUtils耗时监控工具类(线程安全)相关推荐

  1. PyQt之科学使用线程处理耗时任务以及线程通信方法

    目录 前言 PyQt线程科学用法 非科学用法样例 科学用法 线程类 线程通信 线程类在主界面实例化与使用 开启线程 补充(信号的方式实现线程双向通信): 线程类 线程实例化与开启线程挂在后台 发送信号 ...

  2. ScheduledThreadPool 源码解析——定时类线程池是如何工作的

    文章目录 引言 一.ScheduledThreadPool 使用示例 1. 延时类的定时任务 `schedule` 2. 延时类,固定周期执行任务 `scheduleAtFixedRate` 3. 延 ...

  3. 多线程下ArrayList类线程不安全的解决方法及原理

    多线程下ArrayList类线程不安全的解决方法及原理 参考文章: (1)多线程下ArrayList类线程不安全的解决方法及原理 (2)https://www.cnblogs.com/fangting ...

  4. Java集合(实现类线程安全性)

    转载自  Java集合(实现类线程安全性) 1.集合和Map 下图是Java集合的Collection集合体系的继承树: 下图是Java的Map体系的继承树: 对于Set.List.Queue和Map ...

  5. NDK/C++ 耗时统计类TimeUtils

    一.需求分析 在开发阶段中,经常会需要打印出某些方式或步骤的耗时情况,大致需求如下: 能打印出某个步骤的耗时: 有开关可以控制打开和关闭耗时统计: 使用方便. 二.准备工作 之前介绍过一个 log 输 ...

  6. synchronized(互斥线程,类线程和对象线程),一段代码理解

    下面直接运行即可. package com.controller;/*** Created by** @author : zj* @date : 2018-08-20*/public class Te ...

  7. Java性能耗时监控工具

    Java性能耗时监控工具(基于Spring的StopWatch监控工具) 特点 改编自Spring的StopWatch,功能增强,原理不变 代码实现简单,使用更简单 支持Slf4j日志打印,可使用Lo ...

  8. java 基于oshi的系统监控工具类(带网速上行下行)

    java 基于oshi的系统监控工具类(带网速上行下行) 一.pom.xml 二.工具类 1.服务器相关信息 Server.class 2.CPU相关信息 Cpu.class 3.內存相关信息 Mem ...

  9. java 静态类 安全_Java静态static工具类线程安全问题研究

    针对静态方法有以下一些前提: 静态方法和实例方法的区别是静态方法只能引用静态变量,静态方法通过类名来调用,实例方法通过对象实例来调用 每个线程都有自己的线程栈,栈与线程同时创建,每一个虚拟机线程都有自 ...

最新文章

  1. 核磁共振影像数据处理-3-DTI基础、Li‘s have a solution and plan.
  2. HUE配置文件hue.ini 的database模块详解(包含qlite、mysql、 psql、和oracle)(图文详解)(分HA集群和非HA集群)...
  3. vue.js官方文档 PDF
  4. 智源-知乎联合发布大规模用户关系数据集,同步开启10万元竞赛
  5. 一起学 Java(四) File、Try 、序列化、MySQL、Socket
  6. jquery背景自动切换特效
  7. linux查找文件命令 要查找包含某字符
  8. putty, puttycm区别
  9. linux 时间相关的一些总结
  10. 剑指Offer 09 用两个栈实现队列
  11. 在iPad/iPhone上使用Firebug
  12. 愤怒的小鸟python代码_Python 愤怒的小鸟代码实现:物理引擎pymunk使用
  13. 复旦计算机学院软件工程,2019年复旦961软件工程专硕考研初试363+复试经验分享...
  14. OpenCore引导配置说明第十一版说明-基于OpenCore-0.6.4正式版
  15. Bootstrap—各式各样的按钮
  16. excel数据透视表之交叉表分组
  17. 手把手教你php调用短信接口(smsapi)实现发送短信验证码
  18. 收藏 | 自然语言处理(NLP)数据集汇总(附下载链接)
  19. ECharts在线编辑 中国地图数据可视化 展示
  20. 例子解释,pandas的pd.read_csv函数,quoting = 3是什么意思

热门文章

  1. php在线打包(hacklog修改版),wordpress配置记录
  2. 工地反光衣穿戴检测算法
  3. mysql 时间 本周 本月_日本人脑洞最大的奇葩恋爱游戏,本周上架Steam,别在吃饭时玩...
  4. laravel mysql 数组_PHP如何使用laravel 5将数据从数组保存到mysql
  5. PS2019仿制图章工具、图案图章工具
  6. java des解密乱码_des解密不完整,前面几位是乱码的解决办法
  7. win10无限蓝屏_快速解决Win10无限重启的方法
  8. ust (user space tracer)
  9. mysql 微博 数据表_微博数据库如何设计-百度经验
  10. 使用Weevely工具上传一句话木马