分享java压力测试模版类 版本2

来源:互联网 发布:如何评价日本人知乎 编辑:程序博客网 时间:2024/06/11 21:03

        在上一次,我们分享了一个压力测试的模板类,在模板类里面通过继承然后实现重写几个方法即可以实现压力测试,其本质就是由实现者去实现具体的测试逻辑,将功能代码独立抽离出来实现复用。然而,继承存在着一些缺点是无法避免的。比如具体的失去了灵活性,而且如果java不支持多继承,意味着测试类会被限制少了继承其他类的能力,再者之前的代码对外部暴露的接口过多,无法对用户实现彻底的透明。因此对原先的代码采用了Function方式进行重构。

        Function的方式即将函数作为参数传入方法中,由具体的调用者去决定函数的内容,这个刚好是我们需要的,由具体的测试者去实现需要测试的逻辑。可惜在java中并不支持将函数作为参数传入方法中,不能像js那样  function xxx(functionx)去声明调用。不过,在设计模式中有一种叫做命令模式的,我们简单的借用下。

       

public interface Runnable {    /**     * When an object implementing interface <code>Runnable</code> is used     * to create a thread, starting the thread causes the object's     * <code>run</code> method to be called in that separately executing     * thread.     * <p>     * The general contract of the method <code>run</code> is that it may     * take any action whatsoever.     *     * @see     java.lang.Thread#run()     */    public abstract void run();}

        在java的java.util下有这个Runable的接口,只需要实现run方法即可。

public void xxx(Runable r){        r.run();}
        如果有疑问function不是一个接口吗,那apply方法哪里实现的,这样想就对了。如果要体会这种写法怎么做,可以直接new Function()xxxx看看IDE会怎么帮你自动生成一些代码。这个就是由调用xxx的用户去实现function的内容,在运行该方法的处决定function接口的内容,将实现者和调用者解耦。
       接下来是重构过的测试模板类。正确的说不是模板类了,是直接可以运行的功能类了。

       

import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;  import java.util.concurrent.atomic.AtomicLong;      /**  * 通用压力测试类  * Created by lsz on 14-10-24.  */  public class CommonsTest {      int threadNum = 1;      int sleepTime = 1000;      long lastTimes = 0;      int x = 0;      private AtomicLong now = new AtomicLong();      private AtomicLong maxTime = new AtomicLong(0l);      ExecutorService pool = null;      Runnable runnable;      public CommonsTest(int threadNum,Runnable runnable) {        this.runnable = runnable;        this.threadNum = threadNum;          pool = Executors.newScheduledThreadPool(this.threadNum);        }      CommonsTest(int threadNum){          this(threadNum,null);      }      CommonsTest(Runnable runnable){        this(5,runnable);    }        public static CommonsTest create(){          return new CommonsTest(5);      }      public CommonsTest setThreadNum(int threadNum){          this.threadNum = threadNum;          return this;      }      public CommonsTest setApply(Runnable runnable){        this.runnable = runnable;        return this;    }        public void start(){          for(int i = 0 ; i<threadNum;i ++ ){              pool.execute(new TestThread());          }          String format = "---------------------"+"当前1s内的执行数"+"/"+"总的执行数"+"/"+"平均的执行数"+"/"+"执行的时间"+"/"+"最长执行时间";          while(true){              try {                  x++;                  Thread.sleep(sleepTime);              } catch (InterruptedException e) {                  e.printStackTrace();              }              long nowtmp = now.get();              System.out.println(format);              System.out.println("---------------------"+(nowtmp - lastTimes)+"/"+now.intValue()+"/"+(now.intValue()/x)+"/"+x+"/"+maxTime.get()+"ms");              lastTimes = nowtmp;          }      }        class TestThread extends Thread{          public TestThread() {            }          @Override          public void run() {              System.out.println("start------------------"+Thread.currentThread().getName());              while (true){                  try {                      long start = System.currentTimeMillis();                    runnable.run();                    long end = System.currentTimeMillis() - start;                    if(end>maxTime.get()){                          maxTime.set(end);                      }                      now.incrementAndGet();                  } catch (Exception e) {                      e.printStackTrace();                  }                }          }    }  }

         看到这个类,感觉和之前的模板类没啥区别,只是在具体的测试代码调用处从模版方法改成了接口方法。具体的使用也简单了n多。

/** * Created by lsz on 14-10-24. */public class SimpleTest {    public static void main(String[] args) {        new CommonsTest(5,new Runable() {            @Override            public void run {                //这里写压力测试的逻辑代码                // 创建http请求(get方式)                // HttpGet httpget = new HttpGet("http://www.xxx.com/xxx");                //httpclient.execute(httpget);                return true;            }        }).start();    }}

          在这里只需要关心线程数和业务逻辑了,不需要继承任何类,欢迎讨论。





0 0
原创粉丝点击