Java内存模型

一.JMM概念
抽象的概念,描述一组规则或规范,通过这组规范定义了各个变量(实例变量,静态字段和构成数组对象的元素)的访问方式,JVM运行程序的实体是线程,每个线程JVM都会为其创建一个工作内存,工作内存是每个线程的的私有数据区域,java内存模型规定中的变量都存储在主内存,主内存是共享数据,所有线程都能访问,但是线程对变量的操作都必须在工作内存中完成,工作内存存放的是主内存中的副本,线程通信都需要通过主内存来完成。

百度百科:内存模型描述了程序中各个变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存中取出变量这样的底层细节,对象最终是存储在内存里面的,这点没有错,但是编译器、运行库、处理器或者系统缓存可以有特权在变量指定内存位置存储或者取出变量的值。【JMM】(Java Memory Model的缩写)允许编译器和缓存以数据在处理器特定的缓存(或寄存器)和主存之间移动的次序拥有重要的特权,除非程序员使用了volatile或synchronized明确请求了某些可见性的保证。

二.JMM主存工作内存关系图

JMM关系图

工作内存与主内存交互操作,Java内存模型定义了以下八种操作来完成变量的操作更新

lock(锁定):作用于主内存的变量,把一个变量标识为一条线程独占状态。
unlock(解锁):作用于主内存变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
read(读取):作用于主内存变量,把一个变量值从主内存传输到线程的工作内存中,以便随后的load动作使用
load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时将会执行这个操作。
assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋值给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。
store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作。
write(写入):作用于主内存的变量,它把store操作从工作内存中一个变量的值传送到主内存的变量中。

三. 其他相关概念

并发编程的三个基本概念

1.原子性:一个多操作或多个操作要么全部执行完成,要么全都不执行,期间不会被其他因素干扰。
2.可见性:变量被其中一个线程修改时,其他线程能够立即看到修改的值。
3.有序性:程序的执行按照代码的先后顺序执行。

volatile变量规则

1.保证变量的可见性,任意线程对valatile变量的修改后,其他线程是立即可见的;即线程修改变量值后会强制将其刷新到主内存中,其他线程工作内存中变量的缓存值失效,必须向主内存中重新获取
2.禁止指令重排序

volatile可以保证线程可见性且提供了一定的有序性,但是无法保证原子性。在JVM底层volatile是采用“内存屏障”来实现的。观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令,lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
(1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
(2)它会强制将对缓存的修改操作立即写入主存;
(3)如果是写操作,它会导致其他CPU中对应的缓存行无效。

DCL 为什么要加volatile

public class SingleInstance{
	private volatile static SingleInstanceinstance;
	
	public static SingleInstancegetInstance(){       
		if(instance == null){                        
			synchronized(SingleInstance.class){        
				if(instance == null){   
					/**
					*  1.memory = allocate() //分配内存
					*  2.ctorInstanc(memory) //初始化对象
 					*  3.instance = memory //设置instance指向刚分配的地址
					*/            
					instance = new SingleInstance();   
				}
			}
		}
		return instance;                             
	}
}

在多线程的情况下,2 和3 重排序后,instance 只是指向了一段地址,返回的对象并没有初始化,加了volatile后可以禁止指令重排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值