volatile内存语义

volatile是java虚拟机提供的轻量级的同步机制。volatile可以保证可见性和禁止指令重排。

对被volatile修饰的共享变量总是对所有线程是可见的。当volatile被修饰的共享变量被修改后,修改后的值立马就会被其它线程读到。这就是可见性。
禁止指令重排,保证单个volatile变量的读/写具有原子性。但是对于volatile++这种复合操作不具有原子

volatile读的内存语义

当写一个volatile变量时,JMM会把该线程工作内存中对应的共享变量刷新到主内存中。

volatile写的内存语义

当读一个volatile变量时,JMM会把该线程工作内存中对应的共享变量副本设置成无效。线程直接从主内存中读取共享变量

因此volatile读/写可以实现线程间的通信

voliatile内存语义的实现

前面提到voliatile可以禁止指令重排序和保证可见性,为了保证voliatile内存语义,JMM会分别限制编译器和处理器重排序。这种限制主要是通过内存屏障来实现的。

voliatile重排序规则

是否能重排序第二个操作第一个操作普通读/写voliatile读voliatile写普通读/写否voliatile读否否否voliatile写否否> 总结


第一个操作是voliatile读的时候,不管第二个操作是什么都不能重排序
第二个操作是voliatile写的时候,不管第一个操作是什么都不能重排序
第一个操作是voliatile写的时候,第二个操作是voliatile读的时候不能重排序

内存屏障

为了实现voliatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序:

(1)在每个volatile写操作前面插入一个StoreStore屏障
(2)在每个volatile写操作后面插入一个StoreLoad屏障
(3)在每个volatile读操作后面插入一个LoadLoad屏障
(4)在每个volatile读操作后面插入一个LoadStore屏障
在这里插入图片描述

锁的内存语义

锁是Java并发编程中最重要的同步机制。锁除了可以让临界区互斥执行,还可以让释放锁的线程向获取同一个锁的线程发送消息

锁释放的内存语义

当线程释放锁时,JMM会把线程中的工作内存对应的共享变量刷新到主内存中

锁获取的内存语义

当线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区资源必须从主内存中读取共享变量

因此锁的释放/读取可以实现线程间的通信

标签: 内存, 线程, 排序, 模型, JMM, volatile, 语义, voliatile

相关文章推荐

添加新评论,含*的栏目为必填