java 多线程模拟高访问量测试

来源:互联网 发布:腾讯软件 编辑:程序博客网 时间:2024/06/04 00:21

本文模拟10个用户,持续访问Controller方法(适用SpringMVC框架项目,其他框架可借鉴)。


YourJunit为一个线程类,模拟每间隔随机秒数,有一个用户进行访问,到十个用户为止。也可修改for循环,模拟N个用户。

YourThreadTest为一个线程类,私有变量为Controller对象,通过while循环,间隔随机秒数调用Controller的方法,使不断地进行访问。

import org.springframework.context.ApplicationContext;import org.springframework.context.support.FileSystemXmlApplicationContext;import java.util.Random;public class YourJunit extends Thread{    public void run(){        ApplicationContext ac = new FileSystemXmlApplicationContext("classpath:spring-servlet.xml");        YourController yourController = ac.getBean(YourController.class);        //开10个线程,模拟10个用户        for(int i = 0;i < 10; i++){            Thread thread = new YourThreadTest(yourController);            thread.setName(" user NO."+(i+1));            thread.start();            try {                //线程休眠时间1-5秒,每间隔1-5秒开启一个线程,模拟一个用户进行访问                Thread.sleep(1000*(new Random().nextInt(5)+1));            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    public static void main(String[] args){        new YourJunit().start();    }}

import org.apache.commons.lang.time.DateFormatUtils;import java.util.Date;import java.util.Random;public class YourThreadTest extends Thread {    private YourController yourController;    public YourThreadTest(YourController yourController){        this.yourController = yourController;    }    public void run(){        while (true){            yourController.yourMethod();            System.out.println(DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss")+"  "+Thread.currentThread().getName()+"  visit");            try {                //线程休眠时间1-5秒                Thread.sleep(1000*(new Random().nextInt(5)+1));            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}


为什么YourJunit类不用junit的Test,即注解@Test的方式,而是用了main方法?

若使用junit的@Test方式,@Test方法里的语句执行结束,就立即结束,线程不再继续跑。
这个原因和junit的运行机制有关,junit可以理解为一个java程序,且是一个独立的程序。当你用junit执行一个方法,它的大概操作过程是:

  1. 启动Junit程序
  2. 启动过程中会将你要测试的“目标类”及“方法”传递给junit程序。
  3. junit根据信息解析出目标类class文件路径。
  4. 动态加载class文件,加载成内存中的一个java对象。利用反射(具体可以百度下)调用目标方法。

junit执行目标方法的方式是:当方法执行完成后,会立即结束程序。@Teat里方法执行结束了,线程可能还没跑完。但junit不会管这些子线程是否运行完,就直接结束程序了。


如下代码,循环执行结束,运行立即停止,线程也不再继续。

import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.FileSystemXmlApplicationContext;public class YourJunit{    @Test    public  void test(){        ApplicationContext ac = new FileSystemXmlApplicationContext("classpath:spring-servlet.xml");        YourController yourController = ac.getBean(YourController.class);        for(int i = 0;i < 10; i++){            Thread thread = new YourThreadTest(yourController);            thread.setName(" user NO."+(i+1));            thread.start();        }    }}

0 0