java内存模型

似乎任何计算机问题都能够通过加上一个中间件得以解决.
由于处理器运行速度与内存读写速度之间的差异,现代计算机系统加上了一个高速缓存作为内存与处理器之间的缓冲.
基于高速缓存的存储交互很好解决了处理器与内存之间的速度矛盾,但是也引入了一个新的问题缓存一致性问题.
在多处理的计算机系统中,每个处理器都有自己的高速缓存,但是它们共享同一主内存,当多处理器的运算任务涉及同一块内存区域时(多处理器的多线程并发同步问题),将可能导致各自的缓存数据不一致.
除了增加高速缓存,为了使处理器内部的运算单元能被尽量充分利用,处理器可能会对输入的代码进行乱序执行优化,处理器会在计算之后将乱序执行的结果进行重组,保证执行的结果与顺序执行的结果是一样的,因此,要是存在一个计算任务需要依赖另一个计算任务的中间结果,那么其顺序性并不能靠代码的先后顺序来保证.java虚拟机的即时编译器也有类似的指令重排序的优化.
java内存模型的出现是java虚拟机团队试图屏蔽掉各种硬件和操作系统的内存访问差异,以实现java在各平台都能达到一致的内存访问效果.
java内存模型规定,所有的变量 存储在主内存中,此处的主内存与系统的主内存进行类比,因为java虚拟机的主内存是系统主内存的一部分.
每条线程都有自己的工作内存,可以与每个处理器的高速缓存进行类比,线程的工作内存中保存着被该线程使用到的变量的主内存副本拷贝.线程对变量的所有操作在工作内存中完成,而不能直接读写主内存中的变量,不同线程的变量也不能被相互访问.
volatile关键字:1,保证变量对所有线程的可见性,2,禁止指令重排序.

java内存模型的特征
1.原子性
2.可见性
3.有序性
原子性的保证:由java内存模型直接保证原子性变量操作包括,read,load,assign,use,store,和write,我们大致可以认为基本数据类型的访问读写是具有原子性的,例外就是long和double的非原子性协定,synchronized中的操作也是原子性的,其中涉及到lock与unlock操作,提供了更高层次的字节码指令,monitorenter与monitorexit来隐式地使用这两个操作.除此之外还有java中的特定原子类也能实现原子操作.
可见性的保证:普通变量与volatile关键字都能实现可见性,区别就是volatile的特殊规则既保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新,volatile保证了多线程操作时变量的可见性,而普通变量不能保证这一点.除此之外final与synchronized也能保证可见性,可见性是由:"对一个变量执行unlock之前,必须先把此变量同步回主内存中"这条规则实现的,而final的可见性是指,被final修饰的字段在构造器中一旦初始化完成,并且构造器没有将其的this引用传递出去,那么在其他线程中也能看见final字段的值.
有序性的保证:java程序中天然的有序性是指:如果在本线程内观察,所有的操作都是有序的,如果在一个线程中观察另一个线程所有的操作都是无序的.java语言提供了volatile与synchronized两个关键字保证线程之间操作的有序性,volatile本身就包含了禁止指令重排序的语义,synchronized是通过同一时刻只允许一条线程对其进行lock操作这条规则获得的,这条规则决定了持有同一个锁的两个同步块只能串行得进入.

你可能感兴趣的:(java内存模型)