我们已经了解了Java虚拟机的运行时数据区,垃圾收集相关知识,接下来学习虚拟机非常重要的部分

这就是Java内存模型与线程(第12章),这一篇,将主要讲讲内存模型

了解Java内存模型之前,先了解下计算机的操作系统的一些已知事实,还是图解先行:

图片没拍好姑且将就着看吧!这是处理器、高速缓存、主内存间的交互关系

计算机的存储设备与处理器的运算速度通常有几个数量级的差距,因此加入了高速缓存来作为中间的缓冲

在多处理器系统中,每个处理器都有自己的高速缓存,他们共享同一主内存,这引入了一个新问题:缓存一致性

内存模型可以理解为在特定的操作协议下,对特定内存或高速缓存读写访问的过程抽象

处理器可能会对输入代码进行"乱序执行优化",保证执行结果与顺序执行结果一致,但是不保证计算顺序与输入代码顺序一致

有了这个大致的理解,接下来我们看看Java内存模型,你将看到它和前面讲到的何其相似,还是先上图:

  Java内存模型的主要目标是定义程序中各个变量的访问规则,即在

虚拟机中将变量存储到内存和从内存中取出变量的底层细节,不同于

通常所说的变量,这里主要是实例字段,静态字段和构成数组的对象

的元素,不包括局部变量与方法参数(因为这是线程私有的)。

规则:线程对变量的所有操作都必须在工作内存中进行,而不能直接

读写主内存中的变量。工作内存中保存了被该线程使用到的变量的主内

存副本拷贝,volatile变量也不例外

接下来介绍下内存间的交互操作

Java内存模型中定义了8种操作来完成工作内存和主内存间的交互,虚拟机必须保证每一种操作都是原子的,不可再分的

作用于主内存的变量的:lock(锁定),unlock(解锁),read(读取),write(写入)

作用于工作内存的变量:load(载入),use(使用),assign(赋值),store(存储)

将变量从主内存复制到工作内存,需要顺序执行read和load操作

将变量从工作内存同步回主内存,需要顺序执行store和write操作

注意:Java内存模型只要求上述两个操作必须顺序执行,而没有保证是连续执行,意即两个操作之间是可以插入其他指令的

如对主内存的变量a和b进行访问,一种可能出现的顺序是read a,read b,load b,load a

Java内存模型还规定了上述8种操作必须满足的其他规则,篇幅所限。此处不再赘述,有兴趣的可参考本书12.3.2节

volatile型变量的特殊规则

关键字volatile可以说是Java虚拟机提供的最轻量级的同步机制

当一个变量定义为volatile后将具备两种特性:

1、保证此变量对所有线程的可见性(也只保证可见性,不保证原子性)。

  可见性指当一条线程修改了该变量的值,新值对于其他线程来说是可以立即得知的。如上所述,普通变量的值

在线程之间传递需要通过主内存来完成。注意:基于volatile变量的运算在并发下一样是不安全的

volatile修饰的变量在赋值后会多执行一个操作,这个操作相当于一个内存屏障,它的作用是使得本CPU的Cache写

入内存,并引起别的CPU或别的内核无效化其Cache,相当于做了一次"strore和write"操作

2、遇到volatile关键字时可以禁止指令重排序优化

  和处理器会进行"乱序执行优化"类似,虚拟机在执行字节码指令过程中也会进行"指令重排序优化",只要保证

执行结果一致,执行顺序并不保证一致。volatile的读操作性能消耗与普通变量几乎无差别,但是写操作可能会慢

一些,因为他需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行

在下一篇我们将学习下内存模型中比较重要的3个概念,原子性,可见性与有序性

最新文章

  1. jquery checkbox 实现单选
  2. petapoco存储过程
  3. PHP滚动日志
  4. 获取图片中感兴趣区域的信息(Matlab实现)
  5. iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合
  6. (medium)LeetCode 229.Majority Element II
  7. Yum本地源配置
  8. SKShapeNode类
  9. php 设置字符集为utf-8
  10. sqlserver2005级联删除
  11. HDU 4557 非诚勿扰 队列、(记一次失败的SBT尝试)
  12. .net core建站踩坑记录
  13. 在Windows 10 + Python 3.6.5 中用 pip 安装最新版 TensorFlow v1.8 for GPU
  14. wxPython 的简单框架实例
  15. python显示进度条
  16. 实现外卖选餐时两级 tableView 联动效果
  17. 【转】关于HTTP服务器每个客户端2个连接的限制
  18. jmeter接口测试3-正则表达式提取器的使用
  19. 【BIEE】安装好BIEE后,修改默认登录页面不为QuickStart页面
  20. svn与eclipse的集成(第三方插件与eclipse的集成)

热门文章

  1. CTF学习路线指南(附刷题练习网址)
  2. mysql开启慢查询报错:
  3. 6361. 【NOIP2019模拟2019.9.18】鲳数
  4. 解析Spring第四天(Spring中的事物、Spring框架来管理模板类)
  5. sublime上插件的安装与使用
  6. NX二次开发-UFUN导入图框UF_PART_import
  7. macOS cataline 10.15 升级后问题一览
  8. js的线程和同步异步以及console.log机制
  9. 秒懂机器学习---分类回归树CART
  10. Go中的switch fallthrough