Implementing Multi‑Threaded HTTP Load Tests in Java
This article explains how to build two Java load‑testing modes—quantitative and timed—by extending thread‑limit classes, managing GCThread lifecycle, sending HTTP requests with FanLibrary, and correctly cloning request objects to avoid bugs during multithreaded performance testing.
Believe in the theory of ten thousand lines of code!
Continuing from the previous post that introduced abstract classes for timed and quantitative load‑testing modes, this article presents concrete implementations for a single HTTP request object ( HTTPrequestbase) in a multithreaded performance testing framework.
The key points are starting and stopping GCThread in the before() method and implementing the doing() method to send the request and parse the response. Response validation and assertions are omitted because they are highly context‑specific and often unnecessary; monitoring server logs or other metrics can be used instead.
It is crucial to correctly clone objects—both multithreaded class instances and HTTPrequestbase objects—by implementing a clone() method; otherwise, bugs may arise.
Gitee repository: https://gitee.com/fanapi/tester
Quantitative Mode
package com.fun.frame.thead;
import com.fun.base.constaint.ThreadLimitTimesCount;
import com.fun.base.interfaces.MarkThread;
import com.fun.frame.httpclient.FanLibrary;
import com.fun.frame.httpclient.FunRequest;
import com.fun.frame.httpclient.GCThread;
import org.apache.http.client.methods.HttpRequestBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* http request multithread class
*/
public class RequestThreadTimes extends ThreadLimitTimesCount {
static Logger logger = LoggerFactory.getLogger(RequestThreadTimes.class);
public HttpRequestBase request;
/**
* Constructor for multiple executions per thread
* @param request the request to execute
* @param times number of executions per thread
*/
public RequestThreadTimes(HttpRequestBase request, int times) {
super(null, times, null);
this.request = request;
}
/**
* Constructor with marking support
*/
public RequestThreadTimes(HttpRequestBase request, int times, MarkThread mark) {
super(null, times, mark);
this.request = request;
}
protected RequestThreadTimes() { super(); }
@Override
public void before() {
super.before();
GCThread.starts();
}
@Override
protected void doing() throws Exception {
FanLibrary.excuteSimlple(request);
}
@Override
public RequestThreadTimes clone() {
RequestThreadTimes threadTimes = new RequestThreadTimes();
threadTimes.times = this.times;
threadTimes.request = FunRequest.cloneRequest(request);
threadTimes.mark = mark == null ? null : mark.clone();
return threadTimes;
}
}Timed Mode
package com.fun.frame.thead;
import com.fun.base.constaint.ThreadLimitTimeCount;
import com.fun.base.interfaces.MarkThread;
import com.fun.frame.httpclient.FanLibrary;
import com.fun.frame.httpclient.FunRequest;
import com.fun.frame.httpclient.GCThread;
import org.apache.http.client.methods.HttpRequestBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* http request multithread class
*/
public class RequestThreadTime extends ThreadLimitTimeCount {
static Logger logger = LoggerFactory.getLogger(RequestThreadTime.class);
public HttpRequestBase request;
/**
* Constructor for multiple executions per thread
* @param request the request to execute
* @param time number of executions per thread
*/
public RequestThreadTime(HttpRequestBase request, int time) {
super(null, time, null);
this.request = request;
}
/**
* Constructor with marking support
*/
public RequestThreadTime(HttpRequestBase request, int time, MarkThread mark) {
super(null, time, mark);
this.request = request;
}
protected RequestThreadTime() { super(); }
@Override
public void before() {
super.before();
GCThread.starts();
}
@Override
protected void doing() throws Exception {
FanLibrary.excuteSimlple(request);
}
@Override
public RequestThreadTime clone() {
RequestThreadTime threadTime = new RequestThreadTime();
threadTime.time = this.time;
threadTime.request = FunRequest.cloneRequest(request);
threadTime.mark = mark == null ? null : mark.clone();
return threadTime;
}
}Disclaimer: "FunTester" is released for the first time; please follow and discuss, and third‑party reposting is prohibited.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
