JAVA内存模型与线程

JAVA内存模型
JAVA虚拟机规范中试图定义一种JAVA内存模型(JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让JAVA程序在各种平台下都能达到一致的内存访问效果。
JAVA内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。
如图:
JAVA内存模型与线程
volatile关键字
1.当一个线程对volatile修饰的变量修改了之后,新值是对其他线程立即可知的,普通变量不具备这样的特性 需通过主内存传递进行。
volatile 并不是绝对线程安全的 因为对变量的操作不具有原子性,所以我们仍然需要通过synchronized或者java.util.concurrent中的原子类来保证原子性。
2.禁止语义重排序

内存模型的三大特性:
原子性:
上述操作read,load等都是原子性操作
尽管虚拟机没把lock unlock 开放给用户使用但是:
JAVA通过monitorenter,monitorexit来隐式的使用这两个操作,这两个字节码指令反映到JAVA代码中就是同步块,synchronized关键字,因此可以得出,synchronized块之间得操作也具备了原子性。
可见性
JAVA内存模型是通过修改新值同步回主内存,在变量读取之前从主内存刷新变量值这种依赖主内存作为传递媒介得方式来实现可见性得,volatile特殊规则保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新。
final:被final修饰得字段在构造器中一旦初始化完成,并且构造器没有把this引用传递出去,那在其他线程中就能看到final字段得值。
synchronized:对一个变量进行unlock操作时必须将变量同步到主内存中,故保证了线程间得可见性。
有序性:
volatile禁止指令重排序,synchronized则是由 一个变量在同一时刻只允许有一个线程对其进行Lock操作来实现得。