# Java 并发工程：Java 21 最小实验

七组独立实验解释并发机制。所有数据为本地教学数据，不连接电商服务、数据库或博客后台；博客服务器只分发源码和图解。

## 运行环境

- JDK 21：入口同时校验 `java` 和 `javac` 的主版本。本次实际环境是 Java 21.0.1、macOS arm64、Python 3.12。
- Python 3.9+：仅使用标准库，不需要 pip 或 Maven。
- JOL 0.17：只有 MonitorLab 使用；首次需要访问 Maven Central，下载地址与 SHA-256 固定在 `versions.json`。后续使用校验通过的缓存，可以离线运行。
- Linux 可显式设置 `LAB_JAVA_HOME`，本轮没有实机验证 Linux 或 Windows；不把可移植设计当作跨平台实测。

在解压后的源码目录运行，工作目录必须位于源码目录之外：

```bash
# macOS 自动发现 JDK 21；也可以显式指定。
export LAB_JAVA_HOME="$(/usr/libexec/java_home -v 21)"
python3 run.py --work /tmp/java-concurrency-run

# 单组运行，不涉及 JOL 的组不下载依赖。
python3 run.py --work /tmp/java-concurrency-jmm --group JmmLab
```

也可从其他目录用 run.py 的绝对路径执行。运行会清除子进程继承的 JAVA_TOOL_OPTIONS、JDK_JAVA_OPTIONS、_JAVA_OPTIONS 和 CLASSPATH，避免隐含 JVM 参数改变实验；不修改全局 Java 配置。

## 实验对应

| 组 | 用例数 | 验证范围 |
| --- | ---: | --- |
| JmmLab | 5 | 显式拆分自增模型、真实竞争观察、volatile 发布、join 发布、原子计数 |
| AtomicLab | 5 | CAS 成败、身份 ABA、版本拒绝、不可变库存状态、静止后的 LongAdder 总数 |
| MonitorLab | 5 | 互斥与重入、独立实例、Class 监视器、异常释放、JOL 布局 |
| CoordinationLab | 5 | 等待中断、标记清除、条件谓词循环、先 unpark 后 park、blocker 与中断 |
| AqsLab | 5 | 重入计数、排队后完成、中断获取、超时获取、乐观读戳记失效 |
| ContextLab | 4 | 请求残留、异常清理、跨线程不传播、显式捕获与恢复 |
| FutureLab | 6 | 并行汇合、依赖阶段、异常降级、超时边界、取消边界、提交拒绝 |

每项使用显式检查，不需要 `-ea`。异步失败通过 Future 传回主线程；单项同步等待通常有五秒保护，单组 Java 进程最多六十秒。所有测试执行器在退出时关闭并等待终止。时间参数用于触发行为和避免卡死，不是生产超时建议。

运行产物位于 `--work`：`classes/`、`deps/`、各组日志以及该次 `results.json`。单组运行的摘要只代表该组；完整验收请使用不带 `--group` 的命令。本目录的 `results.json` 是作者保存的完整实测快照，运行脚本不会修改它。

## 如何解释结果

- 共 35 个具名用例。本机全量运行两次通过；每次运行的计数竞争值可以不同。
- `split-increment-model` 人为协调读写顺序，证明复合操作可以覆盖更新；不是对真实 `i++` 调度轨迹的观测。
- `volatile-increment-observation` 只检查观察范围，不要求每次丢更新；单次得到 80000 不能证明线程安全。
- LongAdder 在所有工作线程完成后检查 80000，不对并发中的 sum 承诺原子快照。
- 队列实验不保证 A/B 的完成顺序；测试不伪造虚假唤醒，不依赖 GC 即时回收。
- `cancel(true)` 和 `orTimeout` 的实验都先确认 supplier 已运行，后续显式放行，再检查没有收到这两个操作引起的中断；执行器清理在断言之后。
- 没有性能排名、吞吐测试、JMH/jcstress、网络调用或分布式一致性验证。

## JOL 的观测条件

MonitorLab 使用 `-Xms32m -Xmx128m -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:ObjectAlignmentInBytes=8`，通过 `-javaagent` 加载已校验的 JOL full JAR。本机空 Object 布局为 8 字节 Mark Word、4 字节类型信息、4 字节填充，总计 16 字节。测试仅检查尺寸为正，布局数字是环境观测，不是 Java 规范常量。

本机 JOL 报告无法附加 Serviceability Agent。日志保留该提示，未提升权限；不宣称验证了所有内部地址、锁状态或 VM 模式。JOL 的工具许可证与来源见 https://github.com/openjdk/jol ，下载包不重新分发依赖 JAR。

## 源码与证据

文章的 AQS 源码讲解固定为 OpenJDK `jdk-21+35`，API 依据 Java SE 21 文档；本机执行版本单独记录在结果中。旧教程的 AQS 私有方法链和偏向锁参数不能直接套用于本环境。

ZIP 包仅包含本目录的 Java/Python 源码、说明、版本与结果清单、七张 SVG，不包含编译产物、缓存依赖和原始日志。文章中的代码块有些是局部教学片段，完整可编译入口以这七个 Lab 类为准。
