问题情境:数据存储在
搜索服务器,现需测试搜索提供查询更新
接口性能,用户提交更新后立即查询,测试搜索接口实时性
模拟多个用户同时查询提交多条数据,要求用户数、批量提交数、查询和提交时间间隔都为可配
class="java" name="code">
package com.ifeng.sisp.util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import com.ifeng.sisp.pojo.Article;
import com.ifeng.sisp.service.ArticleService;
import com.ifeng.sisp.service.impl.ArticleServiceImpl;
public class TestTreads {
public static List<String> spend = new ArrayList<String>();//用于存储耗时
static String num = null;
static String batch = null;
static String millis = null;
public static void add(long spendTime){
String time = spendTime + "";
spend.add(time);
}
public static void main(String[] args) throws Exception,ParseException{
args = new String[]{"-num","30","-batch","57","-millis","500"};
for(int i=0;i<args.length;i++){
if(args[i].equals("-num")){
i++;
num=args[i];
}else if(args[i].equals("-batch")){
i++ ;
batch=args[i];
}else if(args[i].equals("-millis")){
i++;
millis=args[i];
}else{
System.err.print("no such parameter");
System.exit(0);
}
}
if(num==null){
System.err.print("num can not be null !");
System.exit(0);
}
if(batch==null){
System.err.print("batch can not be null !");
System.exit(0);
}
if(millis==null){
System.err.print("millis can not be null !");
System.exit(0);
}
int threadNum = Integer.parseInt(num);
CountDownLatch threadSignal = new CountDownLatch(threadNum);
int bt = Integer.parseInt(batch);
long mis = Long.parseLong(millis);
for(int i=0;i<threadNum;i++){
submitThread st = new submitThread(i,bt,threadSignal,mis);
Thread thread = new Thread(st);
thread.start();
}
System.out.println("all submit start");
threadSignal.await();
System.out.println("all thread over");
StringBuffer sb = new StringBuffer();
Collections.sort(spend);
for(String s : spend){
sb.append(s).append("\n");
}
FileUtil.write("E:/spendTime.txt", sb.toString());
}
}
class submitThread implements Runnable{
private int num;
private int batch;
private long millis;
private CountDownLatch threadSignal;
ArticleService service = new ArticleServiceImpl();
public submitThread(int num,int batch,CountDownLatch threadSignal,long millis){
this.batch = batch;
this.num = num;
this.threadSignal = threadSignal;
this.millis = millis;
}
public void run(){
String dataServer = "http://ip:port/solr/comment";
for(int i =0;i<1;i++){
System.out.println(Thread.currentThread()+" is run " + i);
//获取文章。进行审核
String source = "http://ip:port/solr/comment/select?q=";
source += "channel:ifeng_comment*" + "+time:[2014-06-20T00:00:00Z+2014-06-20T23:11:20Z]";
source += "&wt=xml" + "&start=" + num*batch + "&rows=" + batch;
try{
source += "&sort=" + URLEncoder.encode("time desc", "utf-8");
}catch(UnsupportedEncodingException e){
e.printStackTrace();
}
List<Article> as = new ArrayList<Article>();
as = MsgConvertUtil.parseArticleXml(source);
List<Article> operate = new ArrayList<Article>();
for(Article a : as){
a.setManualStatus("1");
a.setStatus("2");
operate.add(a);
}
/*if(i%2==0){
for(Article a : as){
a.setManualStatus("2");
a.setStatus("3");
operate.add(a);
}
}else{
for(Article a : as){
a.setManualStatus("1");
a.setStatus("2");
operate.add(a);
}
}*/
String msg = MsgConvertUtil.createArticleXmlTest(operate);
String url = dataServer + "/update?softCommit=true";
// System.out.println(msg);
long start = System.currentTimeMillis();
String res = MsgUtil.sendPostMsg(url, msg, "struts");
long end = System.currentTimeMillis();
System.out.println(res);
int count = 0;
try{
Thread.sleep(millis);
}catch(InterruptedException e){
e.printStackTrace();
}
List<Article> fas = MsgConvertUtil.parseArticleXml(source);
for(Article a : fas){
if(!a.getStatus().equals("2")){
count++;
System.out.println(a.getId()+"未及时"+a.getStatus());
}
}
/*if(i%2==0){
for(Article a : fas){
if(!a.getStatus().equals("3")){
count++;
System.out.println(a.getId()+"未及时"+a.getStatus());
}
}
}else{
for(Article a : fas){
if(!a.getStatus().equals("2")){
count++;
System.out.println(a.getId()+"未及时"+a.getStatus());
}
}
}*/
/*for(Article a : operate){
long s = System.currentTimeMillis();
Article article = service.selectById(a.getId(), dataServer, "audit");
System.out.println(System.currentTimeMillis()-s);
if(!article.getStatus().equals("3"))
System.out.println(article.getId()+"未及时"+article.getStatus());
}*/
long spend = end - start;
if(count!=0)
TestTreads.add(spend);
try{
Thread.sleep(2000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
threadSignal.countDown();
}
}
解析:CountDownLatch类
CountDownLatch类是一个
同步计数器,构造是传入int初始值,每调用一次countDown()方法,计数器减1;调用await()方法会一直阻塞当前
线程,直到计数器为0
CountDownLatch的应用场景:有一个任务想要往下执行,但必须等到其他任务执行完成,这里我是在多个线程执行完更新查询结束后,想要记录所有耗时写入文件