volatile的可见性和有序性原理
请解释volatile关键字如何保证可见性和有序性(禁止指令重排)?底层通过何种内存屏障实现?与synchronized的区别是什么?
回答
编译有声
可见性:
- volatile写操作会强制将本地工作内存中的值刷回主内存。
- volatile读操作会强制从主内存重新读取,使其他线程的修改立即可见。
有序性(禁止指令重排):
- JMM通过内存屏障(Memory Barrier)限制重排序。
- volatile写前插入StoreStore屏障,写后插入StoreLoad屏障。
- volatile读后插入LoadLoad和LoadStore屏障。
- 典型规则:volatile写之前的普通读写不会重排到写之后;volatile读之后的普通读写不会重排到读之前。
与synchronized区别:
- volatile不保证原子性(如i++不是原子的)。
- volatile不会造成线程阻塞,开销小于synchronized。
- synchronized保证原子性、可见性和有序性。
- volatile适用于一写多读的场景(状态标志位、DCL单例)。