高并发场景的模拟测试
@Resource
private ShopServiceImpl shopService;
@Resource
private CacheClient cacheClient;
@Resource
private RedisIdWorker redisIdWorker;
//创建一个固定大小为 500 的线程池,用于并发执行任务。es.submit(task) 将任务提交到线程池进行
private ExecutorService es = Executors.newFixedThreadPool(500);//这是啥,作用是什么,怎么使用
@Test
void redisIdWorkerTest() throws InterruptedException {
//CountDownLatch是线程同步工具,让主线程等待所有子线程完成任务
// 300表示需要调用latch.CountDown()300次才解除阻塞
CountDownLatch latch = new CountDownLatch(300);
Runnable task = () -> { //定义一个任务
for (int i = 0; i < 100; i++) {
long id = redisIdWorker.nextId("order");
System.out.println("id:" + id);
}
latch.countDown();//从300开始递减,为0 latch.await()才能解除阻塞
};
long beginTimestamp = System.currentTimeMillis();//?
for (int i = 0; i < 300; i++) {
es.submit(task);//提交任务给线程池
}
latch.await();//阻塞主线程,直到计数器归0
long endTimestamp = System.currentTimeMillis();
System.out.println(endTimestamp - beginTimestamp);
}
关键点
| 代码 | 作用 |
|---|---|
Executors.newFixedThreadPool | 管理线程复用,避免频繁创建/销毁。 |
CountDownLatch | 确保主线程等待所有并发任务完成。 |
es.submit(task) | 异步执行任务,充分利用多核 CPU。 |
latch.await() | 阻塞主线程,保证统计的耗时准确。 |
这种模式是典型的 多线程压测工具,常用于验证分布式组件的并发性能(如 ID 生成器、数据库连接池等)。
mybatis-plus的相关条件构造器操作
boolean success = seckillVoucherService.update()
.setSql("stock = stock - 1")
.eq("voucher_id", voucherId).update();//TODO 这是什么语法,我没学习,介绍一下它的用法
UPDATE seckill_voucher -- 第一个update()表示要开始UPDATE操作
SET stock = stock - 1 -- setSql()
WHERE voucher_id = ? -- eq()
-- 第二个update()表示执行这条SQL
这段代码使用的是 MyBatis Plus 框架中的条件构造器(Wrapper)语法,这是一种链式编程风格的数据库操作方式。
// 查询也有类似的两次调用
List<User> users = userService.query()
.eq("status", 1)
.list(); // 第一个query()开始查询,最后的list()执行查询
// 删除操作
boolean removed = userService.remove()
.eq("id", userId)
.remove(); // 第一个remove()开始,最后一个执行