Using ThreadLocal for Collect/Uncollect Performance Testing in Java
This article demonstrates how to apply Java's ThreadLocal together with an AtomicInteger to generate unique minisource_id values for a collect‑and‑uncollect workflow, and shows the complete code modifications and performance‑test script used to measure request latency.
Earlier I shared two articles about the ThreadLocal class, and now I present a simple application of ThreadLocal in a performance test that repeatedly performs collect and un‑collect operations.
Requirement and Logic
The requirement is to allow a logged‑in user to cancel or add a favorite for a resource identified by minisource_id. The business rule checks that the outer JSON object's meta field contains a JSON object whose ecode key equals 0.
Logic
First we collect, then we cancel the collection, using this sequence as a test link. In the OKClass we initialize a long List<Integer> ids containing possible minisource_id values, and an AtomicInteger index to mark the current position. The ThreadLocal overrides initialValue() to return ids.get(index.getAndIncrement()), guaranteeing each thread receives a distinct id.
Functional Class Refactor
The relevant code changes are shown below:
/**
* All available ids
*/
public static List<Integer> ids = RWUtil.readTxtFileByNumLine(getLongFile("ids"));
/**
* Index marker
*/
public static AtomicInteger index = new AtomicInteger(0);
/**
* Thread‑local object, not shared between threads
*/
public static ThreadLocal<Integer> minisource_id = new ThreadLocal() {
@Override
public Integer initialValue() {
return ids.get(index.getAndIncrement());
}
};
/**
* Collect OK class
*/
public JSONObject collect(int minicourse_id = minisource_id.get(), int ktype = 0, int grade_id = 12) {
String url = OKClassApi.COLLECT;
def params = getParams();
params.put("minicourse_id", minicourse_id);
params.put("kid_route", [640]);
params.put("ktype", ktype);
params.put("grade_id", grade_id);
params.put("link_source", 1); // 0‑teacher space, 1‑teacher machine
def response = getPostResponse(url, params);
output(response);
return response;
}
/**
* Cancel collect
*/
public JSONObject unCollect(int minicourse_id = minisource_id.get(), int ktype = 0) {
String url = OKClassApi.UNCOLLECT;
def params = getParams();
params.put("minicourse_id", minicourse_id);
params.put("kid_route", [82]);
params.put("ktype", ktype);
def response = getPostResponse(url, params);
output(response);
return response;
}Performance Test Script
The test script, which does not modify the functional code, is as follows:
package com.okayqa.composer.performance.master1_0;
import com.fun.base.constaint.ThreadLimitTimesCount;
import com.fun.frame.execute.Concurrent;
import com.fun.frame.httpclient.ClientManage;
import com.fun.utils.ArgsUtil;
import com.okayqa.composer.base.OkayBase;
import com.okayqa.composer.function.OKClass;
import java.util.concurrent.atomic.AtomicInteger;
class BothCollect extends OkayBase {
static AtomicInteger u = new AtomicInteger(0);
static int times = 0;
static int thread;
public static void main(String[] args) {
ClientManage.init(5, 1, 0, "", 0);
def util = new ArgsUtil(args);
thread = util.getIntOrdefault(0, 200);
times = util.getIntOrdefault(1, 100);
def funs = [];
thread.times { funs << new FunTester(); }
new Concurrent(funs, "收藏和取消收藏").start();
allOver();
}
static int getTimes() { return times; }
static class FunTester extends ThreadLimitTimesCount {
OkayBase okayBase = getBase(u.getAndIncrement());
OKClass driver = new OKClass(okayBase);
public FunTester() { super(null, getTimes(), null); }
@Override
protected void doing() {
def collect = driver.collect();
def value = okayBase.getLastRequestId() + CONNECTOR;
this.threadmark += value;
if (collect.getJSONObject("meta").getIntValue("ecode") != 0) fail(value + "请求出错!");
def collect1 = driver.unCollect();
def value1 = okayBase.getLastRequestId();
this.threadmark += value1;
if (collect1.getJSONObject("meta").getIntValue("ecode") != 0) fail(value1 + "请求出错!");
}
}
}The author, a Tencent Cloud annual author and certified instructor, invites readers to follow for more testing‑related content.
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.
