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

java-concurrency 📚 learning concurrency-foundations · concurrency · parallelism · thread-safety · race-condition · mutability

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 · 简化

一句话总结:并行是"真同时"(多核),并发是"假同时"(分时);线程安全 = 互斥 + 可见性 + 有序性,本质是"多线程共享可变资源时的正确性"。

常见误区

并发 = 大量请求同时处理
并发 = 多任务交替执行,不限定数量
线程安全 = 加锁
线程安全有三种实现(互斥/可见性/有序性),加锁只是互斥的一种手段
无锁 = 线程安全
无锁(CAS)只是原子操作,不保证复合操作的互斥
synchronized 是公平锁
synchronized 是非公平锁

延伸追问

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

速查表

并行 vs 并发:
  并行 = 真同时(多核)     并发 = 假同时(分时)
  并行强调"时间点"          并发强调"时间窗口"
  并行是硬件能力            并发是调度策略

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

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

Anki 候选卡片

Q: 并发和并行的本质区别是什么?
A: 并行=同一时间点真同时(多核);并发=一段时间窗口交替(分时调度)
Q: 线程安全的三个层次?
A: 互斥(一次一个线程改)、可见性(改了对别人可见)、有序性(指令不重排)
Q: 线程安全的前置条件?
A: 多线程 + 共享可变资源,两者同时成立才有意义
Q: synchronized 是公平锁还是非公平锁?
A: 非公平锁

关联题目

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

关联知识

并行=真同时(多核);并发=假同时(分时);线程安全=互斥+可见性+有序性;术语速查覆盖 Java 并发高频报错点
厨房类比:并行像多灶台真同时炒菜;并发像单灶台时间片炒菜;线程安全像规定一次只能一个人进厨房、改动立刻通知所有人、按顺序操作不颠倒
✦ 记 忆 口 诀 ✦
并行硬件/并发调度;线程安全三层=互斥/可见/有序;JMM 规范/JVM 实现;守护线程=JVM 退出条件;Thread.State 6 种
关键可视化
并发 vs 并行
flowchart LR
  subgraph C["并发(假同时)"]
    T["单核"] --> S["时间片调度"]
    S --> R["多任务交替执行"]
  end
  subgraph P["并行(真同时)"]
    M["多核"] --> S2["同一时间点执行"]
    S2 --> R2["真同时"]
  end
  C -.互补.-> P
  P -.约束.-> A["Amdahl 定律<br/>加速比受串行部分限制"]
线程安全三层
flowchart TB
  S["线程安全<br/>= 多线程共享可变资源时正确"] --> M["互斥<br/>一次一个线程改<br/>→ synchronized / Lock"]
  S --> V["可见性<br/>改了对别人可见<br/>→ volatile / synchronized"]
  S --> O["有序性<br/>指令不重排<br/>→ volatile 屏障 / synchronized"]
  S -.消除.-> E["无状态化 / 单线程化<br/>→ Redis / Netty"]
Thread.State 6 种枚举
flowchart TB
  N["NEW<br/>new 后未 start"] --> RUN["RUNNABLE<br/>start() 后<br/>(就绪+运行合一)"]
  RUN --> B["BLOCKED<br/>抢 synchronized 锁失败<br/>(自动进入)"]
  RUN --> W["WAITING<br/>显式 wait/join/park<br/>无超时"]
  RUN --> TW["TIMED_WAITING<br/>显式 wait/sleep/join<br/>带超时"]
  RUN --> T["TERMINATED<br/>run() 返回或异常"]
  B -.抢到锁.-> RUN
  W -.notify/unpark.-> RUN
  TW -.超时/notify.-> RUN
  style N fill:#e0e0e0
  style T fill:#e0e0e0
守护线程 vs 用户线程
flowchart LR
  subgraph JVM["JVM 退出条件"]
    C1["检查是否还有用户线程"]
    C1 --> Yes["有 → 继续运行"]
    C1 --> No["无 → JVM 退出"]
    No --> D["守护线程被强制终止<br/>finally 可能不执行"]
  end
  D -.典型.-> GC["GC 线程 / JIT / Finalizer / Reference Handler"]
知识关系

⬆️ 前置(Prerequisite)

暂无

⚡ 对比(Contrast)

JMM 深度— 本文是并发入口(并行/并发/线程安全三层),JMM 是底层机制深入
🎯 概念 📏 规则 ⚠️ 误区 🔍 追问 ✨ 口诀 共 0 张卡,点击翻面