JMM内存模型学习二
2021/6/17 7:33:09
本文主要是介绍JMM内存模型学习二,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
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内存模型学习二的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程
- 2024-11-26Springboot单体架构搭建资料:新手入门教程
- 2024-11-26Springboot单体架构搭建资料详解与实战教程
- 2024-11-26Springboot框架资料:新手入门教程
- 2024-11-26Springboot企业级开发资料入门教程
- 2024-11-26SpringBoot企业级开发资料详解与实战教程
- 2024-11-26Springboot微服务资料:新手入门全攻略