java并发编程的艺术(三)-----java内存模型
来源:互联网 发布:淘宝账号贷款怎么操作 编辑:程序博客网 时间:2024/06/05 14:08
前言
要想对java内存模型有深入的了解,就必须得了解里面涉及到的顺序一致性内存模型、重排序以及happen-before
顺序一致性模型
顺序一致性模型是计算机科学家们提出的一个理想的参考模型,并不是Java运用的模型!再次强调,是一个理想的理论模型!!Java内存模型也需参考顺序一致性模型进行实现,过程中就需要涉及到重排序和happens-before。
顺序一致性内存模型有两大特性来保证为程序猿提供极强(是极强)的内存可见性
- 一个线程的所有操作都必须按照程序写的顺序来执行
- 所有线程都只能看见一种单一的执行顺序
为什么不按照顺序一致性模型强设计java内存模型
如果完全按照顺序一致性模型来设计,我们的JMM需要对禁止大量的处理器和编译器的优化,这将导致程序的执行性能严重下降。
Java内存模型
在线程与线程之间,java采用了共享内存的方式来通信,而不是消息传递。Java线程之间的通信由Java内存模型进行控制(简称JMM),每个线程都有属于自己的本地内存,里面存放的是该线程对读/写共享变量的副本,而真正的共享变量是存放在主内存中的。
PS:共享变量可以大致理解为JVM在运行时的堆内存里面的数据,因为这里面的数据是线程共享的,而栈里面的数据不属于共享变量因为它是线程私有的。
(此处有图片,待续)
线程与线程之间在通信的时候,无外乎就是将写的共享变量要刷新到主内存,而其他线程要读的时候必须从主内存中去读,这样就可以为程序猿提供了内存可见性保证。
重排序
JMM为了程序在执行代码的时候性能更好,支持处理器和编译器对指令进行重排序,包括编译器优化重排序、指令级优化重排序以及内存系统重排序。
- 编译期优化重排序——不改变单线程语义的情况下改变语句的执行顺序
- 指令级优化重排序——对不存在数据依赖的代码语句在处理器中改变指令的指令的执行顺序。
- 系统内存优化重排序——系统内存对加载和存储顺序不一致
为了避免在重排序时造成存在数据依赖性的语句被重排序了导致程序结果与正确结果不一致的情况,故而引出了happens-before以及用内存屏障实现happens-before
happens-before
定义
如果一个操作的执行结果需要对另一个操作可见,那么这两个操作之间必须拥有happens-before关系
happens-before规则
- 程序顺序规则:线程中的每一个操作happens-before后续的线程操作
- 监视器规则:对锁的释放happens-before对锁的获取
- 传递性
- start()规则:执行线程的start方法要happens-before该线程里面的任意操作
- join()规则:执行ThreadB.join,则执行B线程里面的方法要happens-before join方法返回
根据第一个程序顺序规则,我们可以知道JMM并不强制要求按照happens-before的先后顺序结果执行,只要执行结果不变就行(JSR-133对happens-before关系的定义)
内存屏障
为了严格限制编译期和处理器对某些语句不能进行重排序,JMM会在编译器生成字节码文件的时,在指令序列中内存屏障来禁止摸顶类型的处理器重排序。
- java并发编程的艺术(三)-----java内存模型
- java并发编程的艺术【三】-【一】java内存模型基础
- java并发编程的艺术【三】-【三】内存语义
- <java并发编程的艺术>读书笔记-第三章java内存模型(一)
- 《java并发编程的艺术》读书笔记-第三章Java内存模型(二)
- Java并发编程(三)Java内存模型及volatile
- Java并发编程艺术----读书笔记(三)
- 《Java并发编程的艺术》读书笔记——Java内存模型
- Java并发编程的艺术-第三章之Java内存模型
- 《Java并发编程的艺术》第三章——Java内存模型
- 深入理解Java内存模型(一)——基础 摘录自---<java并发编程的艺术>
- 并发编程笔记(三):Java 内存模型(一)
- 并发编程笔记(三):Java 内存模型(二)
- <并发编程的艺术>读书笔记-第三章java内存模型的基础
- Java并发编程的艺术(上)
- Java并发编程的艺术
- Java并发编程的艺术
- java并发编程(二)《内存模型》
- Email应用
- 字符流是否来自于转换流,为什么?
- 2.排列 (sum)
- Vue2实现组件props双向绑定
- 摆花 动规
- java并发编程的艺术(三)-----java内存模型
- AndroidStudio快捷键整理
- flex布局知识点Beta
- Linux 系统安装
- Java高并发--停止线程和中断线程
- 算法分析与设计第三周
- 利用history.pushState实现前端路由
- Android 的camera.setPreviewCallbackWithBuffer和camera.addCallbackBuffer
- 辗转相除法求模逆运算