---
title: 并发与并行基础 + 线程安全
type: concept
domain: java-concurrency
tags: [concurrency, parallelism, thread-safety, race-condition, mutability]
status: learning
created: 2026-09-26
last_reviewed: 2026-09-26
method: feynman
related_questions:
  - "什么是并发，什么是并行？"
  - "什么是线程安全"
related_knowledge:
  - ./jmm-volatile-cas.md
  - ./synchronized-mechanism.md
  - ./aqs-mechanism.md
anki_cards: 4
interview_rounds:
  - "2026-09-26-round-1-Q1"
  - "2026-09-26-round-1-Q2"
---

# 并发与并行基础 + 线程安全

> 并发/并行的本质区别 + 线程安全的三个层次。是整个并发编程的入口。

## TL;DR（30 秒扫完）

- **并行** = 同一时间点上多个任务真的同时执行，需要多核 CPU；**并发** = 多个任务在一段时间窗口内交替执行，单核通过时间片实现
- 线程安全只在"多线程 + 共享可变资源"同时成立时有意义；无共享/无状态/无状态可变都不构成安全问题
- 线程安全三个层次：**互斥**（一次一个线程改）、**可见性**（改了对别人可见）、**有序性**（指令不重排破坏语义）
- 实现手段谱系：synchronized / Lock / volatile / AtomicXxx / ThreadLocal / 无状态化 / 单线程化

## 关键结论

- **结论 A**：并行是硬件能力（多核），并发是调度策略（分时）；单核只能并发不能并行
- **结论 B**：线程安全的本质是"多线程访问共享可变资源时，任意时刻执行结果都符合预期"
- **结论 C**：线程安全三个层次——互斥（Monitor 互斥）、可见性（解锁刷主存+加锁 reload）、有序性（JIT 禁止指令重排）
- **结论 D**：无状态化是最高级的"线程安全"——Redis 单线程、Netty 单 Reactor、纯函数都靠"不共享可变"来消除问题

## 完整讲解（费曼四步）

### STEP 1 · 概念

并发和并行是两个不同的概念。并行强调"同一时间点真的同时"，并发强调"一段时间窗口内交替执行"。线程安全是指在多线程访问共享资源时，任意时刻的执行结果都符合预期。

### STEP 2 · 大白话

> **类比**：想象一个厨房只有一个灶台（单核）。你做了三道菜（三个任务），但每次只能炒一道，炒完一道再炒下一道——这是**并发**，看起来三道菜一起在做，其实同一时刻只做一道。
>
> 如果厨房有三个灶台（多核），三道菜同时开火——这才是**并行**。
>
> 线程安全就像"多人共用一个工具箱"——如果两人同时拿同一把扳手，可能打架（竞态）；如果规定"一次只能一人拿"（互斥），"谁拿了要在墙上签字"（可见性），"按顺序拿"（有序性），就是线程安全。

### STEP 3 · 底层

#### 并发 vs 并行

| 维度 | 并发 | 并行 |
|------|------|------|
| 同一时间点 | 只执行一个任务 | 多个任务真正同时执行 |
| 硬件要求 | 单核即可 | 必须多核 |
| 调度机制 | OS 分时调度（time-slicing） | OS 跨核分配 |
| 切换代价 | 有上下文切换开销 | 无切换（各核独立） |
| Java 体现 | 线程、线程池、虚拟线程 | 多核 CPU 上的并行流、ForkJoinPool |

#### 线程安全的三个层次

| 层次 | 含义 | 典型问题 | 解决手段 |
|------|------|---------|---------|
| **互斥** | 一次只有一个线程能修改 | 读-改-写竞态（i++ 丢更新） | synchronized、ReentrantLock |
| **可见性** | 改了对其他线程立即可见 | CPU 缓存不一致、JIT 缓存 | volatile（MESI + lock 前缀）、synchronized |
| **有序性** | 指令不能重排破坏语义 | DCL 单例半构造实例 | volatile 内存屏障、synchronized |

#### 实现手段谱系

| 手段 | 类型 | 适用场景 |
|------|------|---------|
| synchronized | 强制同步 | 低竞争、临界区短 |
| ReentrantLock | 强制同步（用户态） | 高竞争、需中断/超时/公平 |
| volatile | 弱化共享 | 单变量读写、状态标志位 |
| AtomicXxx | 无锁原子 | 单变量复合操作（i++） |
| ThreadLocal | 弱化共享 | 线程隔离数据 |
| 不可变对象 | 弱化共享 | String、不可变 DTO |
| 单线程化 | 消除共享 | Redis 主线程、Netty 单 Reactor |

### STEP 4 · 简化

> **一句话总结**：并行是"真同时"（多核），并发是"假同时"（分时）；线程安全 = 互斥 + 可见性 + 有序性，本质是"多线程共享可变资源时的正确性"。

## 常见误区

- **误区 1**：并发 = 大量请求同时处理 → 正确：并发 = 多任务交替执行，不限定数量
- **误区 2**：线程安全 = 加锁 → 正确：线程安全有三种实现（互斥/可见性/有序性），加锁只是互斥的一种手段
- **误区 3**：无锁 = 线程安全 → 正确：无锁（CAS）只是原子操作，不保证复合操作的互斥
- **误区 4**：synchronized 是公平锁 → 正确：synchronized 是**非公平锁**

## Java 并发术语速查表（基础事实纠正）

> 面试高频报错点，集中速查。

### 线程基础

| 概念 | 正确表述 | 常见错误 |
|------|---------|---------|
| **守护线程** | 决定 JVM 是否退出（只剩守护线程才退出），用户线程全结束前 JVM 不退出 | "低优先级线程" / "排在其他线程之后运行" |
| **Thread.State** | 6 种：NEW / RUNNABLE / BLOCKED / WAITING / TIMED_WAITING / TERMINATED | 加"READY"（Java 没有）|
| **BLOCKED vs WAITING vs TIMED_WAITING** | BLOCKED=抢 synchronized 锁失败自动进入；WAITING=显式 wait/join/park 无超时；TIMED_WAITING=带超时的 wait/sleep/join | 三者混为一谈 |
| **中断** | 是**独立标志位**（isInterrupted），不是 State 枚举 | 认为"中断是线程状态" |
| **isAlive()** | 底层 `state != NEW && state != TERMINATED`；NEW 不算存活 | 说成 `isActive()`（没有这个方法）|
| **守护线程创建** | `setDaemon(true)` 必须在 `start()` 前调用，之后抛 `IllegalThreadStateException` | 认为可以任意时机设置 |

### 锁基础

| 概念 | 正确表述 | 常见错误 |
|------|---------|---------|
| **锁升级** | JDK **1.5** 引入（不是 1.8）| 说 1.8 |
| **偏向锁现状** | JDK **15** 默认关闭、JDK **18** 彻底移除 | 认为仍在用 |
| **静态 synchronized 锁对象** | 锁 `Class<T>.class`（JVM 全局单例） | "整个类"（不是类型）|
| **Mark Word 位置** | 在**对象头**（Mark Word 8 字节 + Klass Pointer）| 说成"线程头" |
| **锁对象** | 是"对象引用"，不是"代码块"或"类型" | 混淆锁的粒度 |

### 关键字与内存模型

| 概念 | 正确表述 | 常见错误 |
|------|---------|---------|
| **JMM** | JLS 定义的**规范**（抽象规则），JVM 是**实现** | 认为 JMM = JVM |
| **三大并发问题** | **原子性 / 可见性 / 有序性** | 说"一致性"（那是 CAP/事务概念）|
| **volatile 语义边界** | **单变量一次读写**，不是"一段代码" | 认为 volatile 可以圈住代码块 |
| **内存屏障** | **CPU 指令**，由 JIT/编译器显式插入 | 说成"内核指令" |
| **synchronized 锁的对象** | 三种：`this` / `Class<T>.class` / 显式对象 | 混淆静态和非静态 |

## 延伸追问

1. **Java 中有哪些并发编程工具？分别解决什么问题？**
   - 线程（基础）、线程池（复用）、ExecutorService（抽象）、CompletableFuture（编排）、ForkJoinPool（分治）、AtomicXxx/CAS（无锁）、虚拟线程（轻量）
2. **并发和并行哪个性能更好？**
   - 并行扩展性线性（受核数约束），并发受上下文切换开销影响；Amdahl 定律限制并行加速比
3. **虚拟线程为什么让并发更简单？**
   - M:N 调度（少量载体线程映射大量虚拟线程）、栈内存只占几十 KB、同步阻塞不占平台线程

## 速查表（面试前 30 秒扫完）

```
并行 vs 并发：
  并行 = 真同时（多核）     并发 = 假同时（分时）
  并行强调"时间点"          并发强调"时间窗口"
  并行是硬件能力            并发是调度策略

线程安全三层：
  互斥 = 一次一个线程改     → synchronized / Lock
  可见性 = 改了对别人可见   → volatile / synchronized
  有序性 = 指令不重排       → volatile 屏障 / synchronized

实现手段：
  强同步：synchronized / ReentrantLock
  无锁：AtomicXxx / CAS
  弱化：ThreadLocal / 不可变 / 无状态
  消除：单线程化（Redis / Netty）
```

## 关联题目（题库）

- [ ] 《什么是并发，什么是并行？》— 2026-09-26 Round 1 Q1, ⭐⭐⭐⭐
- [ ] 《什么是线程安全》— 2026-09-26 Round 1 Q2, ⭐⭐⭐

## 关联知识

- [JMM 与 volatile/CAS](./jmm-volatile-cas.md)
- [synchronized 实现与三特性](./synchronized-mechanism.md)
- [AQS 四大核心机制](./aqs-mechanism.md)
- [Netty 无锁化设计](./netty-lockfree.md)

## Anki 候选卡片

1. **正**：并发和并行的本质区别是什么？**反**：并行=同一时间点真同时（多核）；并发=一段时间窗口交替（分时调度）
2. **正**：线程安全的三个层次？**反**：互斥（一次一个线程改）、可见性（改了对别人可见）、有序性（指令不重排）
3. **正**：线程安全的前置条件？**反**：多线程 + 共享可变资源，两者同时成立才有意义
4. **正**：synchronized 是公平锁还是非公平锁？**反**：非公平锁

---

*最后更新：2026-09-26*
