← 每日面试题 学习看板

synchronized是如何保证原子性、可见性、有序性的?

面试题/00java/02Java 并发编程/06线程同步与锁机制/synchronized是如何保证原子性、可见性、有序性的?.md

面试记录 2026-09-26

题目:synchronized 是如何保证原子性、可见性、有序性的?

难度:high

标签:java/lock, general/knowledge

评分:⭐⭐☆☆☆

我的回答

Xenon 是通过锁去保证这一整个的线程并发的处理的。通过锁来保证原子性,内核级的锁,它在指令中添加了锁的指令,去确保锁内只有同一个线程在执行。可见性方面,由于它通过锁控制,其他线程是不会进入的,其他线程会被阻塞,放到阻塞队列中,并不存在可见性问题,当前线程可见当前内容。有序性方面,它也是通过它是通过公平锁来实现的,顺序的去处理锁的线程。如果是这个有序性指的是指令重排,那么它也是通过锁的指令,在内核程序去保证锁指令重排的不发生。

点评

优点:抓到核心方向——synchronized 通过"锁"机制保证原子性;大致意识到可见性来自其他线程进不来

不足:严重错误——synchronized 不是公平锁而是非公平锁;有序性理解错误(混淆了指令重排与线程获取顺序);未说三大特性的底层机制(Monitor 互斥、解锁刷内存、内存屏障);未提 happens-before 规则

补充:原子性=Monitor 互斥、可见性=解锁刷内存+加锁 reload、有序性=JIT 禁止重排;synchronized 是非公平锁;volatile 只保证可见+有序,synchronized 三个都保证

完整讲解(权威版)

最后更新:2026-10-26 · 基于第 3 次作答

L1 · 30 秒速记

结论:synchronized 通过 Monitor + 内存屏障 + JIT 禁重排,同时保证原子性、可见性、有序性;是 volatile 的超集。 关键词:Monitor owner · 解锁刷主存 + 加锁 reload · happens-before 第 17 条 边界:synchronized 是非公平锁;volatile 只保可见+有序,不保原子性

L2 · 核心讲解

核心考点定位:能否说清"原子性 = 互斥"、"可见性 = 解锁刷内存"、"有序性 = 禁止指令重排"这三条底层机制,以及 happens-before 规则。

机制链(4 环):

  1. 并发三大问题(原子性/可见性/有序性)→ 单一手段难以同时解决 → 需要复合机制
  2. synchronized 原子性 ← Monitor 互斥:每个对象隐含 Monitor,含 owner 指针;线程 CAS 抢 owner 成功后独占执行 → 其他线程进不来
  3. 可见性 ← 解锁刷主存 + 加锁 reload:解锁时 StoreLoad 屏障强制刷回主存,加锁时强制从主存 reload → 加锁 reload 是常被漏掉的一半
  4. 有序性 ← JIT 禁重排 + 内存屏障:synchronized 块内指令不被重排到块外,CPU 层 StoreLoad 屏障保跨块顺序
  5. JMM 第 17 条 happens-before:解锁 → 后续加锁 → 是"可见性 + 有序性"的契约基础

证据锚点(去重 ≥12):

对比与权衡:

关键字原子性可见性有序性实现机制开销
volatile❌✅✅内存屏障中
synchronized✅✅✅Monitor + 内存屏障 + JIT 禁重排高
AtomicXxx(CAS)✅✅(volatile 语义)✅CPU cmpxchg低
ReentrantLock✅✅✅AQS(CLH 队列)中

权衡:synchronized 是"三合一"的最强保证,但开销最大;高竞争场景应退回到 Lock / CAS / 分段方案。

常见误区:

  1. 错误:"synchronized 是公平锁" → 正确:synchronized 是非公平锁,JVM 内部不保证先到先得 → 为什么:需要公平性用 ReentrantLock(true)
  2. 错误:"有序性指线程获取锁的顺序" → 正确:有序性指指令级重排——JIT 不重排 synchronized 块内指令 → 为什么:JMM 的有序性是 JIT 优化边界,不是线程调度
  3. 错误:"synchronized 只保证原子性" → 正确:synchronized 同时保证原子性 + 可见性 + 有序性 → 为什么:Monitor 机制天然包含三者
  4. 错误:"可见性靠解锁刷主存就够了" → 正确:可见性靠解锁刷主存 + 加锁时 reload——两半缺一不可 → 为什么:加锁时不 reload 可能读到旧值
  5. 错误:"volatile 能保证原子性" → 正确:volatile 只保可见性 + 有序性,不保原子性(i++ 三步仍会交错) → 为什么:volatile 语义边界是"单变量一次读写"

适用边界:

延伸追问(≥3)

  1. synchronized 能保证原子性,为什么不用 volatile 也能保证可见性和有序性?
  1. synchronized 是公平锁吗?为什么说是非公平锁?
  1. happens-before 有哪些规则?
  1. Monitor 的 owner 指针在对象头的什么位置?
  1. volatile 和 synchronized 能同时用吗?

面试者参考回答(400–700 字)

【结论】 synchronized 同时保证三个特性:原子性、可见性、有序性,但每一条的底层机制不同。

【三点】

第一,原子性 = Monitor 互斥。每个对象隐含一个 Monitor,含 owner 指针。线程进入 synchronized 块时,先尝试用 CAS 把 owner 设成自己;成功了独占执行,失败了在队列里等。重量级锁状态下其他线程挂起到 entryList 阻塞等待,轻量级锁下通过自旋 CAS 竞争。所以从"互斥"角度看,原子性其实是锁的基本性质——你进得去,别人就进不来。

第二,可见性 = 解锁刷内存 + 加锁 reload。解锁时把工作内存里的修改强制刷回主存,并加 StoreLoad 内存屏障;加锁时丢弃本地工作内存,强制从主存 reload 最新值。JMM 第 17 条规则总结:对一个 synchronized 块的解锁,happens-before 后续对同一把锁的加锁。这是并发编程可见性的契约基础。

第三,有序性 = 禁止指令重排。这里的有序性不是"线程获取锁的顺序",而是指令级重排——JIT 编译器不会把 synchronized 块内部的指令重排到块外部。CPU 层面的 StoreLoad 屏障也保证了跨块的指令顺序。比如 DCL 单例不加 volatile,new 指令会被重排成"分配内存→赋引用→初始化构造器",其他线程可能看到半构造实例。

【边界】 对比 volatile:volatile 只保可见性和有序性,不保原子性(i++ 三步仍会交错);synchronized 通过互斥把三步包成一个整体,所以三个特性都保。但 synchronized 开销更大,高竞争场景要慎重。另外提醒:synchronized 是非公平锁,需要公平性用 ReentrantLock(true)。


面试记录 2026-10-17(第 2 次)

题目:synchronized 是如何保证原子性、可见性、有序性的?

难度:high

标签:java/lock, general/knowledge

评分:⭐⭐⭐⭐☆(4/5)

练习次数:2

我的回答

synchronized在不同锁等级下使用不同的方式来实现原子,可见,有序的,以重量锁来说 通过cpu提供的lock指令来实现多线程的互斥,实现一个线程在临界区域进行原子操作的; 通过释放锁后,通知主存,唤醒其他阻塞线程,来实现多线程的可见性的; 通过happend-before语义,内存屏障来实现阻止指令重排实现有序性的

点评

优点:三条机制映射正确——原子性 = lock 指令互斥、可见性 = 释放刷主存、有序性 = 屏障禁重排。比首次(2026-09-26,2/5,且当时把 synchronized 误说成公平锁)大幅进步。

不足:缺 Monitor/entryList 机制、加锁时 reload、"unlock happens-before lock" 规则;"通知主存唤醒其他线程"表述偏松——唤醒靠 monitor,可见靠刷主存,是两件事。

补充:synchronized 是非公平锁;volatile 只保可见+有序,synchronized 三者都保。

ℹ️ 完整讲解见上方首次记录(2026-09-26)

面试记录 2026-10-26(第 3 次)

题目:synchronized 是如何保证原子性、可见性、有序性的?

难度:high

标签:java/lock, general/knowledge

评分:⭐⭐⭐☆☆(3/5)

练习次数:3

我的回答

synchronized 在重量级锁的时候,通过操作系统底层指令来实现原子性、可见性、有序性的;其中原子性是通过 lock 命令和 unlock 命令来控制,临界范围内的代码是不会被其他线程介入,其他线程会被操作系统阻塞等待 unlock 命令执行完成后才会去争抢锁持有;可见性是在锁退出的时候会刷新主存,让其他线程可见;有序性是依据 happend-before 规则来实现的。

点评

优点:

不足(比第 2 次退步):

对比历史:

与 2026-10-17 第 2 次作答的对比

维度2026-10-17(第 2 次,4/5)2026-10-26(第 3 次,3/5)
原子性机制(lock 指令)✅✅
可见性(刷主存)✅⚠️ 只说解锁,漏加锁 reload
有序性(happens-before)✅⚠️ 只说 hb 规则,漏 JIT 禁重排
Monitor 机制⚠️ 未展开❌ 未提
非公平锁属性❌ 未提❌ 未提
与 volatile 对比❌ 未提❌ 未提
评分4/53/5

结论:第 3 次退步——Monitor 机制和加锁 reload 两个核心点缺失。建议下一轮复习重点专项复习 synchronized 三特性的底层机制。

完整讲解见 2026-09-26 首次记录(本文件上方)