在 Java 中,多线程代码的测试比单线程更复杂,核心是验证正确性、线程安全、并发行为和性能。下面从常用方法、工具、示例和注意事项几个层面系统说明。
@Test
public void testMultiThread() throws InterruptedException {
int threadCount = 10;
Thread[] threads = new Thread[threadCount];
AtomicInteger count = new AtomicInteger(0);
for (int i = 0; i < threadCount; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < 1000; j++) {
count.incrementAndGet();
}
});
}
for (Thread t : threads) t.start();
for (Thread t : threads) t.join();
assertEquals(10000, count.get());
}
✅ 适合:
❌ 缺点:
@Test
public void testConcurrencyRepeat() throws InterruptedException {
for (int i = 0; i < 100; i++) {
testMultiThread();
}
}
✅ 多次运行增加竞态条件暴露概率
@Test
public void testWithLatch() throws InterruptedException {
int n = 5;
CountDownLatch start = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(n);
for (int i = 0; i < n; i++) {
new Thread(() -> {
try {
start.await(); // 等统一开始
// 业务逻辑
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
end.countDown();
}
}).start();
}
start.countDown(); // 同时开始
end.await(); // 等全部结束
}
✅ 模拟“同时并发”
AtomicXXX避免 i++ 问题
ExecutorServiceExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<?>> futures = new ArrayList<>();
for (int i = 0; i < 100; i++) {
futures.add(pool.submit(() -> {
// 业务
}));
}
for (Future<?> f : futures) f.get();
pool.shutdown();
用于测试 JVM 并发语义
@JCStressTest
@Outcome(id = "1", expect = Expect.ACCEPTABLE)
public class VolatileTest {
volatile int x;
@Actor
void actor1() { x = 1; }
@Actor
void actor2(IntResult1 r) { r.r1 = x; }
}
✅ 专门发现:
@Test(threadPoolSize = 10, invocationCount = 100)
public void testConcurrent() {
// 并发执行
}
Map<String, String> map = new ConcurrentHashMap<>();
// 多线程 put / get
✅ 是否存在:
Object lock1 = new Object();
Object lock2 = new Object();
new Thread(() -> {
synchronized (lock1) {
synchronized (lock2) {}
}
}).start();
new Thread(() -> {
synchronized (lock2) {
synchronized (lock1) {}
}
}).start();
配合:
jstack❌ 只在单线程下测试
❌ 只跑一次
❌ 忽略 JVM 优化(重排、缓存)
❌ 用 System.out.println 调试并发
✅ 业务正确性:JUnit + ExecutorService
✅ 并发语义:JCStress
✅ 性能 & 稳定性:JMeter / Gatling
✅ 问题定位:jstack / Arthas
如果你有具体代码(如线程池、锁、并发容器),我可以直接帮你写针对性测试用例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。