龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > JAVA开发 >

Java 1.5中面向方面(AOP)编程[组图](7)

时间:2009-12-23 15:42来源:未知 作者:admin 点击:
分享到:
取样(Sampling) 我现在有办法把StackTraceElement数组转换为@Status注解堆栈。这种操作比表明看到的更加有用。Java 1.5中的另一个新特性--线程反省(introspect

   取样(Sampling)

  我现在有办法把StackTraceElement数组转换为@Status注解堆栈。这种操作比表明看到的更加有用。Java 1.5中的另一个新特性--线程反省(introspection)--使我们能够从当前正在运行的线程中得到准确的StackTraceElement数组。有了这两部分信息之后,我们就可以构造JstatusBar的另一种实现。StatusManager将不会在发生方法调用的时候接收通知,而是简单地启动一个附加的线程,让它负责在正常的间隔期间抓取堆栈跟踪信息和每个步骤的状态。只要这个间隔期间足够短,用户就不会感觉到更新的延迟。

  下面使"sampler"线程背后的代码,它跟踪另一个线程的经过:

  class StatusSampler implements Runnable
  {
  private Thread watchThread;

  public StatusSampler (Thread watchThread)
  {
  this.watchThread = watchThread;
  }

  public void run ()
  {
  while (watchThread.isAlive()) {
   // 从线程中得到堆栈跟踪信息
   StackTraceElement[] stackTrace =watchThread.getStackTrace();
   // 从堆栈跟踪信息中提取状态消息
   List<Status> statusList =StatusFinder.getStatus(stackTrace);
   Collections.reverse(statusList);
   // 用状态消息建立某种状态
   StatusState state = new StatusState();
   for (Status s : statusList) {
    String message = s.value();
    state.push(message);
   }

   // 更新当前的状态
   StatusManager.setState(watchThread,state);
   //休眠到下一个周期
   try {
    Thread .sleep(SAMPLING_DELAY);
   } catch (InterruptedException ex) {}
  }

  //状态复位
  StatusManager.setState(watchThread,new StatusState());
  }
  }

  与增加方法调用、手动或通过重构相比,取样对程序的侵害性(invasive)更小。我根本不需要改变建立过程或命令行参数,或修改启动过程。它也允许我通过调整SAMPLING_DELAY来控制占用的开销。不幸的是,当方法调用开始或结束的时候,这种方法没有明确的回调。除了状态更新的延迟之外,没有原因要求这段代码在那个时候接收回调。但是,未来我能够增加一些额外的代码来跟踪每个方法的准确的运行时。通过检查StackTraceElement是可以精确地实现这样的操作的。

  通过线程取样实现JStatusBar的代码可以在peekinginside-pt2.tar.gz文件的/code/05_sampling目录中找到。

  在执行过程中重构字节码

  通过把取样的方法与重构组合在一起,我能够形成一种最终的实现,它提供了各种方法的最佳特性。默认情况下可以使用取样,但是应用程序的花费时间最多的方法可以被个别地进行重构。这种实现根本不会安装ClassTransformer,但是作为代替,它会一次一个地重构方法以响应取样过程中收集到的数据。

  为了实现这种功能,我将建立一个新类InstrumentationManager,它可以用于重构和不重构独立的方法。它可以使用新的Instrumentation.redefineClasses方法来修改空闲的类,同时代码则可以不间断执行。前面部分中增加的StatusSampler线程现在有了额外的职责,它把任何自己"发现"的@Status方法添加到集合中。它将周期性地找出最坏的冒犯者并把它们提供给InstrumentationManager以供重构。这允许应用程序更加精确地跟踪每个方法的启动和终止时刻。

精彩图集

赞助商链接