关于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. }

关于UtilTimerStack类的使用--XWork2、Struts2内置性能诊断类的更多相关文章

  1. struts2内置拦截器和自定义拦截器详解(附源码)

    一.Struts2内置拦截器 Struts2中内置类许多的拦截器,它们提供了许多Struts2的核心功能和可选的高级特 性.这些内置的拦截器在struts-default.xml中配置.只有配置了拦截 ...

  2. 扩展PHP内置的异常处理类

    在try代码块中,需要使用throw语句抛出一个异常对象,才能跳到转到catch代码块中执行,并在catch代码块中捕获并使用这个异常类的对象.虽然在PHP中提供的内置异常处理类Exception,已 ...

  3. day28 面向对象:反射,内置函数,类的内置方法

    面向对象进阶博客地址链接: http://www.cnblogs.com/Eva-J/articles/7351812.html 复习昨日内容: # 包 # 开发规范 # # hashlib # 登录 ...

  4. 2018.11.20 Struts2中对结果处理方式分析&struts2内置的方式底层源码剖析

    介绍一下struts2内置帮我们封装好的处理结果方式也就是底层源码分析 这是我们的jar包里面找的位置目录 打开往下拉看到result-type节点 name那一列就是我们的type类型取值 上一篇博 ...

  5. Struts2内置校验器——完整实例代码

    一.校验器的配置风格 1.字段校验器: <field name="被校验的字段"> <field-validator type="校验器名"& ...

  6. 洗礼灵魂,修炼python(42)--巩固篇—type内置函数与类的千丝万缕关系

    type函数的隐藏属性 相信大家都知道内置函数type是用来查看对象的数据类型的.例: 那比如我对int类查看类型呢? 有朋友会说,int是内置类啊,用自定义的应该不会这样,我们自定义一个类呢? 还是 ...

  7. python基础之反射内置方法元类

    补充内置函数 isinstance(obj,Foo)   # 判断obj是不是foo的实例 issubclass()      # 判断一个类是不是另一个类的子类 反射 什么是反射? 通过字符串来操作 ...

  8. python类详细说明、常用内置方法和self的作用

    一.类的定义 在Python中,一切皆对象,即便是类本身,也是一种type类型的特殊对象. class Person: def __init__(self, name, age): self.name ...

  9. python类与对象-如何派生内置不可变类型并修其改实例化行为

    如何派生内置不可变类型并修其改实例化行为 问题举例 自定义一种新类型的元组,对传入的可迭代对象,我们只保留 其中int类型且值大于0的元素,例如 IntTuple([1, -1, 'abc', 6, ...

随机推荐

  1. expandableListView的divider该溶液显示在黑色

    黑色是divider高度.如何让他成为透明的啊? 布局例如以下:   <ExpandableListView android:layout_width="wrap_content&qu ...

  2. linux学习(一个) 在unbuntu通过添加新的用户

    最近安装了双系统,开始折腾unbuntu该.Linux系统是一个多用户操作系统,非常多的人才完整的操作需要管理员权限,完全管理员权限是非常重要的.人谁是刚开始学习,般用户的权限即可了,相对于刚開始学习 ...

  3. android adb 不同的方式使用特定的解释

    本文介绍windows 在程序中使用adb 方法.没有引进adb 该命令. 1) 启动adb 流程.获得输出从管道. 这样的方式的弊端有多少,我也不知道.反正就是各种问题吧.可是眼下我问过非常多朋友. ...

  4. Java程序猿JavaScript学习笔记(14——扩大jQuery UI)

    计划和完成这个例子中,音符的顺序如下: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScr ...

  5. C# DateTime结构的常用方法

    在项目开发中,经常会碰到日期处理.比如查询中,可能会经常遇到按时间段查询,有时会默认取出一个月的数据.当我们提交数据时,会需要记录当前日期,等等.下面就看看一些常用的方法. 首先,DateTime是一 ...

  6. HDU1061-Rightmost Digit(高速功率模)

    pid=1061">主题链接 题意:求n^n的个位数的值. 思路:高速幂求值 代码: #include <iostream> #include <cstdio> ...

  7. hexo 部署至Git遇到的坑

    查找资料的时候发现了next这个博客主题,next!非常的漂亮,顺手查看了hexo的相关部署. Hexo官方介绍 Hexo 是一个快速.简洁且高效的博客框架.Hexo 使用 Markdown(或其他渲 ...

  8. 对“demo!demo.Index+HookProc::Invoke”垃圾收集的类型已委托回调。这可能会导致应用程序崩溃、损坏和数据丢失。当传递委托给非托管代码,托管应用程序必须让这些委托保持活着

    对"demo!demo.Index+HookProc::Invoke"垃圾收集的类型已委托回调.这可能会导致应用程序崩溃.损坏和数据丢失.当传递委托给非托管代码,托管应用程序必须承 ...

  9. 每天收获一点点------Hadoop之初始MapReduce

    一.神马是高大上的MapReduce MapReduce是Google的一项重要技术,它首先是一个编程模型,用以进行大数据量的计算.对于大数据量的计算,通常采用的处理手法就是并行计算.但对许多开发者来 ...

  10. C++“窗体”程序设计启蒙

    [摘要]本文以C++菜菜鸟(仅仅须要学习了C++数据类型和控制结构就可以)为目标读者,用求解一元二次方程作为实例,展示窗体式程序的开发过程,获得初步体验.写作目的包含:(1)让学生通过模仿,开发出类似 ...