并发检查看什么
并发缺陷在测试里常常不可复现,所以评审是主要的发现手段。检查重点是共享可变状态是否有保护、多把锁的获取顺序是否一致、阻塞操作是否有超时与取消、以及是否在持锁状态下调用外部代码或回调——最后这类是死锁的常见来源。
基本信息
| 检查重点 | 共享可变状态、锁顺序、超时与取消、锁内调用 |
|---|---|
| 追问内容 | 线程模型、不变量、锁保护的具体范围 |
| 替代方向 | 不可变数据、串行化处理、消息传递减少共享 |
| 现实约束 | 竞态问题在 CI 上往往复现不了,不能留给测试兜底 |
逐项看什么
- 共享可变数据:加锁保护还是改为消息传递,锁粒度是否合理。
- 锁顺序:多把锁时获取顺序是否全局一致,避免交叉等待形成死锁。
- 超时与取消:阻塞操作是否有上限,取消后资源与状态如何收敛。
- 锁内调用外部代码或回调:常见死锁来源,应尽量移到锁外执行。
- 初始化与发布:单例、惰性初始化是否有正确的可见性与同步保证。
并发缺陷类型
| 类型 | 表现 | 看什么 |
|---|---|---|
| 竞态 | 结果依赖执行时序 | 共享状态是否有一致的保护机制 |
| 死锁 | 互相等待,请求挂住 | 锁顺序与锁内调用 |
| 活锁/饥饿 | 反复重试但不推进 | 重试策略与公平性 |
| 可见性问题 | 读到过期值或半初始化对象 | 发布方式与内存模型约束 |
| 资源泄漏 | 并发压力下句柄耗尽 | 取消与异常路径的资源释放 |
并发缺陷难复现:评审时问清线程模型与不变量,比只读代码更有效。
遇到依赖口头的时序假设(如「这个字段只被主线程读写」)时,要求把它变成代码层面的约束或加注释说明来源。