You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

验证ArrayList并发修改异常:多线程触发registry方法的单元测试是否正确?

单元测试实现问题分析

你的这个单元测试实现存在多处错误,完全无法达到验证并发修改异常的目标,核心问题如下:

  • 变量名不匹配:你定义的异常触发标记是AtomicBoolean terminate,但捕获ConcurrentModificationException时调用的是endExecution.set(true),两个变量完全无关,哪怕真的抛出了目标异常,也不会修改terminate的值,后续的断言永远都会通过,根本检测不到异常。
  • 测试前提不成立:你要测试的registry()方法已经加了synchronized修饰,只要该方法内部对customerData这个ArrayList的所有操作都没有外部并发读写的情况,多线程调用该方法时会串行执行,本来就不会触发并发修改异常,测试逻辑和你的目标场景完全不匹配。
  • CountDownLatch逻辑错误:你初始化latch的计数是100,但每个线程的while循环中每执行一次registry()就会调用一次latch.countDown(),只要10个工作线程累计跑满100次就会触发latch.await()返回,主线程直接往下执行,测试运行时长完全不可控,很可能还没触发并发场景就已经跑完了。
  • 断言逻辑完全写反:你的测试目标是验证存在并发修改异常,预期结果应该是异常触发后标记位为true,但你写的assertEquals(terminate.get, false)是验证没有抛出异常,完全不符合测试目标。
  • 资源未释放:测试结束后没有调用ExecutorService.shutdown()关闭线程池,会产生线程驻留的问题。

优化建议

如果要复现ArrayList的并发修改异常,你可以按以下逻辑调整:

  1. 先确认registry()方法的synchronized修饰是否要保留,如果是要测加锁前的并发问题,先去掉该修饰符,或者构造其他线程同时读写customerData的场景。
  2. 统一异常标记变量名,捕获到目标异常后正确修改标记位。
  3. 调整并发逻辑:可以固定每个线程执行N次registry()调用,累计总调用量上万次提升触发并发问题的概率,也可以给单测加超时时间避免无限卡死。
  4. 修正断言逻辑:确认预期结果是触发异常后标记位为true。
  5. 测试结束后主动关闭线程池。

内容的提问来源于stack exchange,提问作者explorer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 01:45:04