并发学习(五) — JAVA内存模型与同步规则

一、Java内存模型(JMM):

         它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。一个线程如何和何时能看到其他线程共享变量的值,以及在必须时如何同步访问共享变量。

        JVM运行程序的实体是线程,而每个线程创建时JVM都会为其创建一个工作内存(有些地方称为栈空间),用于存储线程私有的数据,而Java内存模型中规定所有变量都存储在主内存,主内存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主内存拷贝的自己的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主内存,不能直接操作主内存中的变量,工作内存中存储着主内存中的变量副本拷贝(私有拷贝)。

       


二、Java内存区域:

        堆:运行时的数据区,由垃圾回收来负责的,优点是 可以动态分配内存大小,(生存区)也不用事先告诉编译器,因为它是在运行时动态分配内存的,垃圾收集器会自动回收不再使用的对象。缺点: 由于是运行时动态分配内存,存取速度相对就比较慢一些。

        栈:存取速度比堆要快,仅次于计算机里的寄存器,栈里的数据时共享的,但是存在栈中的数据大小与生存区必须是确定的,缺乏一些灵活性。 栈中主要存放一些基本的数据类型变量,比如小写的int,short,long ,byte,调用栈,本地变量存放在栈上,一个本地变量也可以是引用,指向堆中对象。本地变量是存在线程栈上的,尽管这些方法所处的对象处于堆上,一个对象的成员变量可能会随着对象自身存放在堆上,不管这个成员变量是原始类型还是引用类型,本地变量是存在线程栈上的,尽管这些方法所处的对象处于堆上,静态成员变量跟随着类的定义一起存放在堆上,存放在这个堆上的对象可以被所持有对这个对象的引用线程访问,当一个线程能访问这个对象,那么也能访问这个对象的成员变量,如果两个线程同时调用同一个方法的同一个成员变量,但是每一个线程都拥有这个成员变量的私有拷贝


三、硬件架构:

    多个CPU,有的CPU还有多核,同时运行多个线程。每个CPU上的线程是可以并行执行的,每个CPU都包含一系列的寄存器,它们是CPu内存的基础。访问速度远大于主存的速度。所以内存和CPU之间有高速缓存,可能还有多级缓存,主存是很大的。

四、JMM与硬件架构的模型:


         硬件内存架构没有区别线程,栈和堆。对于硬件来说,都分布在主内存里,可能部分堆,栈分布在CPU缓存中或寄存器中

         线程间共享变量在主内存里,每个线程都有一个私有的本地内存,他是JAVA内存模型的抽象概念,并不是真实存在的,它涵盖了缓存,缓冲区,以及其他的硬件和编译器的优化,存的是一个副本。

        比如线程A从主内存拿到1放到自己的本地内存A,执行+1,再把2写回主内存。两个线程间的不同步性。



五、Java内存模型的的同步8中操作:


同步的8种操作:


同步规则:



猜你喜欢

转载自blog.csdn.net/jae_wang/article/details/80350025