Java内存模型
什么是java内存模型(JMM)
这里参考heaven-Wang博客里面的定义:
java内存模型,定义了JVM在计算机内存中的工作方式;
JMM定义了多线程之间的共享变量的可见性以及如何在需要的时候对共享变量进行同步;
一般并发编程中有两个问题要解决:线程之间的通信和同步:
通信是指线程之间以何种机制来交换信息
同步是指程序中用于控制不同线程操作发生相对顺序的机制
2 两种并发模型: 消息传递和内存共享;
java的并发使用内存共享模型; 对于消息通信是隐式的,而同步是显式进行的;
– JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证;
–JMM是语言级别的内存模型,它确保不同编译器和不同处理器平台上,通过禁止特定类型的编译器重排序和处理器重排序,为程序员提供内存可见性保证;对于语言级别的理解应当是,屏蔽了不同处理器内存模型的差异,在不同的处理器平台上为Java程序员呈现一个一致的内存模型;在JMM设计时,考虑两个关键因素:
1 程序员对内存模型的使用;2 编译器和处理器对内存模型的实现;
JMM在这两者中间找一个平衡点: 为保证程序员提供足够的可见性保证之后,尽量放宽对 编译器和处理器 的限制;–因为,在编译器和处理器过程中,会对程序指令的执行顺序进行优化,—重排序的概念;happens-before 是JMM最核心的概念
因此虽然定义了许多的happens-before规则; 但有的情况下可能是没有必要的—对于重排之后会改变程序执行结果的–JMM不允许重排;
但对于不会改变结果的重排序,JMM不做要求;
—-因此,有的happens-before 并不总是有效的;
另一方面: JMM的原则是: 只要不改变程序的执行结果(单线程和正确同步的多线程程序),底层想怎么优化都可以; 甚至可以 消除一个锁, 取消volatile 关键字的修饰等;
从上面一段的描述,可以知道: happens-before的两条:–也是JSR 对happens-before关系的定义:
1 如果一个操作happens-before 于另一个操作,那么第一个操作的结果对第二个操作可见 且第一个操作的执行顺序排在第二个操作之前;
2 两个操作间存在happens-before关系,并不意味着Java平台的具体实现必须按照指定的关系来执行,如果 重排序之后的执行结果(对这两个操作来说的吧)与未重排序的结果一致,则允许这种重排序;
与as -if-serial 语义有相同的含义:
只不过,as-if-serial是保证单线程的执行结果不变,而happens-before是保证多线程的执行结果不变: 这样做的目的还是为了在不该变程序执行结果的前提下,尽可能的提高程序执行的并行度;;
java并发编程的艺术-笔记