Skip to content

第12章 Java内存模型测试报告

测试时间: 2026-03-29
测试环境: Windows, JDK 17, Maven 3.9+
测试类: com.linsir.abc.core.jvm.jmm.JMMTest


1. 测试概述

本次测试针对Java内存模型(JMM)相关代码进行验证,共执行 12个测试用例,全部通过。

测试范围

  • volatile关键字可见性和原子性
  • synchronized关键字线程安全性
  • 线程状态转换
  • happens-before规则
  • 并发读写综合场景

2. 测试结果汇总

指标数值
测试用例总数12
通过12
失败0
错误0
跳过0
总耗时1.976秒

结果: ✅ 全部通过


3. 详细测试结果

3.1 Test volatile flag visibility

  • 测试方法: testVolatileFlag()
  • 测试内容: 验证volatile状态标志位的可见性
  • 执行结果: ✅ 通过
  • 关键输出:
    Worker-Thread is working...
    Worker-Thread is working...
    Worker-Thread stopped.
  • 验证点: 主线程修改running标志位后,工作线程能够立即看到并停止

3.2 Test volatile singleton DCL

  • 测试方法: testVolatileSingleton()
  • 测试内容: 验证DCL单例模式的正确性
  • 执行结果: ✅ 通过
  • 测试参数:
    • 线程数: 100
    • 验证点: 所有线程获取的实例ID相同
  • 验证点: volatile防止指令重排序,确保单例对象正确初始化

3.3 Test volatile does not guarantee atomicity

  • 测试方法: testVolatileNotAtomic()
  • 测试内容: 验证volatile不能保证复合操作的原子性
  • 执行结果: ✅ 通过
  • 关键数据:
    Expected: 50000
    Actual: 49566  (小于期望值)
  • 验证点: volatile计数器在多线程环境下出现数据竞争,证明volatile不能保证i++的原子性

3.4 Test AtomicInteger atomicity

  • 测试方法: testAtomicCounter()
  • 测试内容: 验证AtomicInteger的原子性保证
  • 执行结果: ✅ 通过
  • 关键数据:
    Expected: 50000
    Actual: 50000
  • 验证点: AtomicInteger通过CAS操作保证原子性,结果与期望值一致

3.5 Test synchronized counter

  • 测试方法: testSynchronizedCounter()
  • 测试内容: 验证synchronized计数器的线程安全性
  • 执行结果: ✅ 通过
  • 关键数据:
    Expected: 50000
    Actual: 50000
  • 验证点: synchronized保证复合操作的原子性,无并发问题

3.6 Test synchronized memory visibility

  • 测试方法: testSynchronizedVisibility()
  • 测试内容: 验证synchronized的内存可见性保证
  • 执行结果: ✅ 通过
  • 关键输出:
    Thread-251 wrote: 42
    Thread-252 read: 42
  • 验证点: 写线程写入42后,读线程能够正确读取到42,证明synchronized保证可见性

3.7 Test thread state transitions

  • 测试方法: testThreadState()
  • 测试内容: 验证线程状态的正确转换
  • 执行结果: ✅ 通过
  • 验证状态:
    • NEW → RUNNABLE → TIMED_WAITING → TERMINATED
  • 验证点: 线程状态转换符合Java线程模型规范

3.8 Test thread implementation methods

  • 测试方法: testThreadImplementation()
  • 测试内容: 验证3种线程实现方式
  • 执行结果: ✅ 通过
  • 验证内容:
    1. 继承Thread类
    2. 实现Runnable接口
    3. 实现Callable接口(带返回值)
  • 关键输出:
    Thread running: Test-Thread-1
    Runnable running: Test-Runnable-1
    Callable running: Test-Callable-1

3.9 Test happens-before monitor lock rule

  • 测试方法: testHappensBeforeMonitorLock()
  • 测试内容: 验证happens-before监视器锁规则
  • 执行结果: ✅ 通过
  • 验证点: unlock操作happens-before后续lock操作,保证可见性

3.10 Test happens-before volatile variable rule

  • 测试方法: testHappensBeforeVolatile()
  • 测试内容: 验证happens-before volatile变量规则
  • 执行结果: ✅ 通过
  • 验证点: volatile写happens-before后续volatile读,通过传递性保证前面操作的可见性

3.11 Test ReadWriteCounter performance

  • 测试方法: testReadWriteCounter()
  • 测试内容: 验证ReadWriteCounter的性能和正确性
  • 执行结果: ✅ 通过
  • 关键数据:
    ReadWriteCounter: 10 readers, 100 reads each, completed in 1ms
  • 验证点: volatile读操作性能优异,10个线程各读100次仅需1ms

3.12 Test concurrent read and write

  • 测试方法: testConcurrentReadWrite()
  • 测试内容: 综合并发读写测试
  • 执行结果: ✅ 通过
  • 测试参数:
    • 写线程: 10个,每线程100次自增
    • 读线程: 20个,每线程100次读取
  • 关键数据:
    Expected: 1000
    Actual: 1000
  • 验证点: 多线程并发读写下,计数器保持数据一致性

4. 关键发现

4.1 volatile vs synchronized/Atomic

特性volatilesynchronizedAtomicInteger
可见性✅ 保证✅ 保证✅ 保证
原子性❌ 不保证复合操作✅ 保证✅ 保证
性能最优一般较好
适用场景状态标志位、DCL复合操作计数器、累加器

4.2 测试数据对比

并发计数测试(50线程 × 1000次):

  • volatile: 49566/50000 (99.13%,有数据竞争)
  • synchronized: 50000/50000 (100%,线程安全)
  • AtomicInteger: 50000/50000 (100%,线程安全)

5. 结论

  1. volatile 能够保证可见性和有序性,但不能保证复合操作的原子性
  2. synchronized 能够保证原子性、可见性和有序性,适用于需要互斥的场景
  3. Atomic类 通过CAS操作提供无锁的原子性保证,性能优于synchronized
  4. happens-before规则 是判断线程安全的重要依据
  5. 所有12个测试用例全部通过,代码实现正确

6. 附录

6.1 测试命令

bash
# 运行所有JMM测试
mvn test -Dtest=JMMTest

# 运行单个测试
mvn test -Dtest=JMMTest#testVolatileFlag

# 生成测试报告
mvn test -Dtest=JMMTest -DreportFormat=plain

6.2 测试环境信息

Apache Maven 3.9.x
Java version: 17.0.x
OS: Windows 10/11
CPU: Multi-core processor
Memory: 16GB+

报告生成时间: 2026-03-29
测试执行状态: ✅ 全部通过

Released under the MIT License.