题目:synchronized 是如何保证原子性、可见性、有序性的?
难度:high
标签:java/lock, general/knowledge
评分:⭐⭐☆☆☆
Xenon 是通过锁去保证这一整个的线程并发的处理的。通过锁来保证原子性,内核级的锁,它在指令中添加了锁的指令,去确保锁内只有同一个线程在执行。可见性方面,由于它通过锁控制,其他线程是不会进入的,其他线程会被阻塞,放到阻塞队列中,并不存在可见性问题,当前线程可见当前内容。有序性方面,它也是通过它是通过公平锁来实现的,顺序的去处理锁的线程。如果是这个有序性指的是指令重排,那么它也是通过锁的指令,在内核程序去保证锁指令重排的不发生。
优点:抓到核心方向——synchronized 通过"锁"机制保证原子性;大致意识到可见性来自其他线程进不来
不足:严重错误——synchronized 不是公平锁而是非公平锁;有序性理解错误(混淆了指令重排与线程获取顺序);未说三大特性的底层机制(Monitor 互斥、解锁刷内存、内存屏障);未提 happens-before 规则
补充:原子性=Monitor 互斥、可见性=解锁刷内存+加锁 reload、有序性=JIT 禁止重排;synchronized 是非公平锁;volatile 只保证可见+有序,synchronized 三个都保证
最后更新:2026-10-26 · 基于第 3 次作答
结论:synchronized 通过 Monitor + 内存屏障 + JIT 禁重排,同时保证原子性、可见性、有序性;是 volatile 的超集。 关键词:Monitor owner · 解锁刷主存 + 加锁 reload · happens-before 第 17 条 边界:synchronized 是非公平锁;volatile 只保可见+有序,不保原子性
核心考点定位:能否说清"原子性 = 互斥"、"可见性 = 解锁刷内存"、"有序性 = 禁止指令重排"这三条底层机制,以及 happens-before 规则。
机制链(4 环):
证据锚点(去重 ≥12):
对比与权衡:
| 关键字 | 原子性 | 可见性 | 有序性 | 实现机制 | 开销 |
|---|---|---|---|---|---|
| volatile | ❌ | ✅ | ✅ | 内存屏障 | 中 |
| synchronized | ✅ | ✅ | ✅ | Monitor + 内存屏障 + JIT 禁重排 | 高 |
| AtomicXxx(CAS) | ✅ | ✅(volatile 语义) | ✅ | CPU cmpxchg | 低 |
| ReentrantLock | ✅ | ✅ | ✅ | AQS(CLH 队列) | 中 |
权衡:synchronized 是"三合一"的最强保证,但开销最大;高竞争场景应退回到 Lock / CAS / 分段方案。
常见误区:
ReentrantLock(true)i++ 三步仍会交错) → 为什么:volatile 语义边界是"单变量一次读写"适用边界:
ReentrantLock(true)【结论】 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)。
题目: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)
题目:synchronized 是如何保证原子性、可见性、有序性的?
难度:high
标签:java/lock, general/knowledge
评分:⭐⭐⭐☆☆(3/5)
练习次数:3
synchronized 在重量级锁的时候,通过操作系统底层指令来实现原子性、可见性、有序性的;其中原子性是通过 lock 命令和 unlock 命令来控制,临界范围内的代码是不会被其他线程介入,其他线程会被操作系统阻塞等待 unlock 命令执行完成后才会去争抢锁持有;可见性是在锁退出的时候会刷新主存,让其他线程可见;有序性是依据 happend-before 规则来实现的。
优点:
不足(比第 2 次退步):
对比历史:
| 维度 | 2026-10-17(第 2 次,4/5) | 2026-10-26(第 3 次,3/5) |
|---|---|---|
| 原子性机制(lock 指令) | ✅ | ✅ |
| 可见性(刷主存) | ✅ | ⚠️ 只说解锁,漏加锁 reload |
| 有序性(happens-before) | ✅ | ⚠️ 只说 hb 规则,漏 JIT 禁重排 |
| Monitor 机制 | ⚠️ 未展开 | ❌ 未提 |
| 非公平锁属性 | ❌ 未提 | ❌ 未提 |
| 与 volatile 对比 | ❌ 未提 | ❌ 未提 |
| 评分 | 4/5 | 3/5 |
结论:第 3 次退步——Monitor 机制和加锁 reload 两个核心点缺失。建议下一轮复习重点专项复习 synchronized 三特性的底层机制。