• 关于UtilTimerStack类的使用--XWork2、Struts2内置性能诊断类


    关于UtilTimerStack类的使用--XWork2、Struts2内置性能诊断类

    一、UtilTimerStack做什么用的?
    这个本来是Xwork2(Struts2的核心)的相关的工具类,可以用来测试一些逻辑操作所消耗的时间(以毫秒为单位),其本身使用一个 ArrayList作为存放ProfilingTimerBean的容器,而行为以Stack栈(后入先出)为主。在打印的时候支持缩进显示,显示相关的 调用关系。类ProfilingTimerBean主要是用来记录一些相关的信息,例如主要标识、开始时间、结束时间。

    二、UtilTimerStack如何使用?
    UtilTimerStack的调用方法不多且都为静态函数,但在调用之前必须先开启诊断功能,

    主要有以下三种方法开启:

    •    在启动时加入参数: -Dxwork.profile.activate=true
    •    在使用前、或者静态代码区、或者Servlet的初始化、或者Filter的初始化 加入代码:

                               UtilTimerStack.setActivate(true);
                          或者 System.setProperty("xwork.profile.activate", "true");
                          或者 System.setProperty(UtilTimerStack.ACTIVATE_PROPERTY, "true");

    •    也支持xml来定义相关拦截器(必须开启dev模式和加入Profiling拦截器):

                         <action ... > 
                          ...
                          <interceptor-ref name="profiling">
                              <param name="profilingKey">profiling</param>
                          </interceptor-ref>
                          ...
                         </action>
                         再通过URL访问: http://host:port/context/namespace/someAction.action?profiling=true
                         或者通过代码加入请求参数: ActionContext.getContext().getParameters().put("profiling", "true);

    指定超时打印功能,只有当运行时间超过时才会进行记录,开启方法:

    •     在启动时加入参数: -Dxwork.profile.mintime=1000
    •     或者代码加入:System.setProperty(UtilTimerStack.MIN_TIME, "" + 1000);


    例子代码:

    1. public static void main(String[] args) throws InterruptedException {  
    2.     String name = "test used time:";  
    3.     UtilTimerStack.setActive(true);  //开启诊断功能  
    4.     System.setProperty(UtilTimerStack.MIN_TIME, "" + 1000); //设置最小的超时记录时间  
    5.     UtilTimerStack.push(name); //顶节点的记录Bean  
    6.     subMethod(0);  
    7.     UtilTimerStack.pop(name);//对应的出栈操作,名称与入栈时相同  
    8. }  
    9. public static void subMethod(int i) throws InterruptedException{  
    10.     System.out.println(i + "");  
    11.     UtilTimerStack.push(i + " times");  
    12.     if(i<3) subMethod(i+1); //递归调用,会产生缩进,最后调用i=3时不足1000,不记录  
    13.     Thread.sleep(i * 300);  
    14.     UtilTimerStack.pop(i + " times");  
    15. }  



    代码输出:
    0
    1
    2
    3
    2010-3-21 16:16:52 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
    信息: [1828ms] - test used time:
      [1828ms] - 0 times
        [1828ms] - 1 times
          [1516ms] - 2 times
     


    三、UtilTimerStack内部机制?

    ProfilingTimerBean类结构
        主要成员:
        List<ProfilingTimerBean> children;//记录子节点为,打印时需要
        ProfilingTimerBean parent = null;//记录父节点,顶点的父节点为null
        String resource;//主要标识,名称
        long startTime;//开始时间
        long totalTime;//结束时间


    UtilTimerStack的压栈(push)动作:

    1. public static void push(String name)  
    2. {  
    3.     if (!isActive())  //判断是否开启诊断功能  
    4.         return;  
    5.     //创建新的记录Bean,并用setStartTime方法开始记录  
    6.     ProfilingTimerBean newTimer = new ProfilingTimerBean(name);  
    7.     newTimer.setStartTime();  
    8.     //判断如果有父节点,则添加到父节点的Child中.  
    9.     ProfilingTimerBean currentTimer = (ProfilingTimerBean) current.get();  
    10.     if (currentTimer != null)  
    11.     {  
    12.         currentTimer.addChild(newTimer);  
    13.     }  
    14.     //再把新建的节点设置为当前的线程的局部变量current中.  
    15.     current.set(newTimer);  
    16. }  


       

    UtilTimerStack的出栈(pop)动作:

    1. public static void pop(String name)  
    2. {  
    3.     if (!isActive())  
    4.         return;  
    5.     //获取当前线程的变量current.get()返回顶部记录Bean  
    6.     ProfilingTimerBean currentTimer = (ProfilingTimerBean) current.get();  
    7.     //if the timers are matched up with each other (ie push("a"); pop("a"));  
    8.     //测试出栈的记录Bean是否与要求的对应,如果不对应则log下错误,并打印栈里的记录Bean信息  
    9.     //如果与要求的标识对应,则把父节点设置为当前节点.  
    10.     if (currentTimer != null && name != null && name.equals(currentTimer.getResource()))  
    11.     {  
    12.         currentTimer.setEndTime();  
    13.         ProfilingTimerBean parent = currentTimer.getParent();  
    14.         //如果当前节点为根节点,则开始打印这个栈里面的记录Bean信息  
    15.         if (parent == null)  
    16.         {  
    17.             printTimes(currentTimer);  
    18.             //清理当前的线程局部变量,防止一些容器使用线程池的方式处理请求.  
    19.             current.set(null);  
    20.         }  
    21.         else  
    22.         {  
    23.             //设置父节点为当前节点.  
    24.             current.set(parent);  
    25.         }  
    26.     }  
    27.     else  
    28.     {  
    29.         //当出栈的顺序不对称时,把剩下的都打印出来  
    30.         if (currentTimer != null)  
    31.         {  
    32.             printTimes(currentTimer);  
    33.             current.set(null);  
    34.             LOG.warn("Unmatched Timer.  Was expecting " + currentTimer.getResource() + ", instead got " + name);  
    35.         }  
    36.     }  
    37.   
    38. }  
  • 相关阅读:
    java-工具代码
    idea-常用快捷键
    idea-环境配置
    mysql-常用命令
    Java IO流学习总结
    Java类加载机制
    Struts2标签 %{ } %{# }详解
    EL语法
    SQL语句
    在servlet转向jsp页面的路径问题
  • 原文地址:https://www.cnblogs.com/quchengfeng/p/4930922.html
Copyright © 2020-2023  润新知