JAVA 内存模型(一) 概念理解

      学习JAVA内存模型,可以帮助我们理解数据在内存中的分布、变化等细节,让我们在多线程开发中,拥有

对数据更强的掌控力,能让我们开发出更稳定、更优秀的程序。

 

一、内存模型定义

     A memory model describes, given a program and an execution trace of that program, whether the execution trace is a legal execution of the program. For the Java programming language, the memory model works by examining each read in an execution trace and checking that the write observed by that read is valid according to certain rules;

      大概意思是:内存模型是描述一个程序的执行路径是否合法。对于JAVA 语言来说,内存模型是检查每一次的读写操作,根据定义的规则,判定这些操作是否有效。

      这里仅仅是定义了一个规范,是一种抽象的概念。

       

 

二、目标:

    JAVA 内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。此处的变量(Variavle) 于JAVA编程中所说的变量有所区别,它包括了实例字段、静态字段、和构成数组对象的元素,但不包括局部变量与方法参数,因为后者是线程私有的,不会被共享,也就不会存在竞争问题。

 

 

三、主内存与工作内存

    JAVA 内存模型中主内存和工作内存的概念,有点类似于电脑里面的内存和高速缓存的概念,线程使用的数据库在主内存中,然后对数据的操作,为了获得更快的速度,会放到寄存器和高速缓存中。JAVA 内存模型规定所有的变量都存储在主内存中,而工作内存会存放用到的变量的副本拷贝,线程对所有变量的操作都在工作内存中进行,而且不同线程不能访问对方工作内存中的变量,只能通过主内存进行进行。这里通过图例,很好明白:

    

 

 

 

 

四、内存间的交互操作

    主内存和工作内存之间的具体交互协议,即变量如何从主内存到工作内存,然后又从工作内存回到主内存的实现细节,JAVA 内存模型定义了以下8中操作完成,虚拟机实现时,必须保证下面的每一种操作都是原子的、不可分割的(对于double long 类型在有些平台上允许例外)。

    1.lock(锁定):作用于主内存的变量,它把变量表示成为一条线程独占的状态。

    2.unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,解锁后才能被其他线程锁定。

    3.read(读取):作用于主内存的变量,它把主内存的变量值传输到线程对应的工作内存中,等待load

    4.load(载入):作用于工作内存的变量, 它把从read操作从主内存中得到的变量值,放入到工作内存的变量副本中。

    5.use(使用):作用于工作内存的变量,它把工作内存的变量的值传递给执行引擎,每当虚拟机遇到一个需要使用的变量的值的字节码指令时,将会执行这个操作。

    6.assigin(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作。

    7.store(存储):作用于工作内存的变量,它把工作内存中的一个变量的值传送到主内存中,以便write操作

    8.write(写入):作用于主内存的变量,它把store 操作从工作内存中得到的变量值放到主内存变量中。

 

 

    上诉概念可能都点麻烦,我给个栗子:快过年了,我家买了很多肉,准备做腊肉香肠,现在放冰箱(主内存),如果只能在一个地方(lock)腌制,首先从冰箱取出来(read),然后拿到后院腌制的地方(load工作内存),然后让一个腌制箱腌制(use),腌制好了拿出来,就是腌肉了(assigin).然后拿回去家里(store),最后由放回冰箱存起来,过年吃(write).当然栗子~。~ 仅描述过程,没加入副本的概念,方便理解嘛!

 

五、内存交互限制和顺序

    内存交互中,有一些限制和顺序的,比如从主内存-->工作内存,顺序执行read-->load操作、如果是变量从工作内存同步回主内存,顺序执行store-->write 操作。

    注意:JAVA 内存模型只要求上面两个操作顺序执行,但是并不保证连续执行。加入读取主内存变量a,b,那么顺序可能是read a,read b,load b,load a.同时,JAVA 内存模型还规定了其他规则:

    1.不允许read、load 和 store、write操作之一,单独出现。即只要read 了,必须完成load 操作,只要store 必须完成write 操作。

 

    2.不允许一个线程丢弃它最近的assign操作,即变量再工作内存中发生变化后,必须同步到主内存。

    

    3.不允许一个线程无原因的(无sssign操作)把工作内存中数据同步到主内存。

    

    4.一个新的变量只能在主内存中诞生,不允许工作内存中直接使用一个未被初始化(load/assign) 的变量,也就是说对一个变量实施use、store操作之前,必须先执行过了assign和load操作。

 

    5.一个变量同一时刻只允许一条线程对其lock操作,但是lock操作可以被同一个线程执行多次,同时解锁的时候也要执行相同的unlock操作。

    

    6.如果对一个变量执行lock操作,那将会清空工作内存中的此变量的值,在执行引擎使用这个变量钱,需要从新执行load 或 assign 操作初始化变量值。

 

    7.如果A线程lock住a变量,只能由A线程unlock,未lock的变量,不能unlock。而且A线程不能unlock B线程lock住的变量。

 

    8.在一个变量执行unlock之前,必须先把此变量同不回主内存中(store-->write)

 

 

小结:

    1.关于JAVA 内存模型规范,我没有仔细研究,仅仅参考一些书籍。

    2.关于内存模型的知识,理论比较重,章节就少分享点,希望大家在空闲时间了解,加深影响,对编程细节很有帮助。

    3.学习JAVA 内存模型,可以做一些实际的例子,或者自己有自己的想法,加深记忆理解,不然容易忘记了,写代码的时候多考虑一些这方面的东西。

    4.有什么不好的地方,欢迎提出建议,我再改进~。~

    

 

    

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值