2. Java内存模型

Java内存模型指定了JVM和计算机内存是如何进行协作

Java内存模型的原理

Java内存被分为线程栈和堆
栈:JVM中的每个线程拥有一个自己的线程栈,线程栈中包含当前调用方法的信息,所有被调用方法的本地变量。
堆:java应用程序中的所有对象,与线程无关。

JVM内存模型
  • 局部变量==>栈==>线程安全
  • 局部对象==>引用在栈,对象在堆==>可能安全
  • 对象方法里面的局部变量==>对象在堆,局部变量在栈==>线程安全
  • 对象里面的成员变量==>堆==>线程不安全
  • 静态类==>堆==>线程不安全
public class MyRunnable implements Runnable() {

    public void run() {
        methodOne();
    }

    public void methodOne() {
        int localVariable1 = 45;

        MySharedObject localVariable2 =
            MySharedObject.sharedInstance;
        //... do more with local variables.
        methodTwo();
    }

    public void methodTwo() {
        Integer localVariable1 = new Integer(99);
        //... do more with local variable.
    }
}

public class MySharedObject {

    //static variable pointing to instance of MySharedObject

    public static final MySharedObject sharedInstance =
        new MySharedObject();

    //member variables pointing to two objects on the heap
    public Integer object2 = new Integer(22);
    public Integer object4 = new Integer(44);

    public long member1 = 12345;
    public long member1 = 67890;
}

硬件内存架构

电脑硬件架构
  • 一个现代计算机通常由两个或者多个CPU。其中一些CPU还有多核。
  • 每个CPU都包含一系列的寄存器,它们是CPU内存的基础。
  • 每个CPU可能还有一个CPU缓存层。CPU访问缓存层的速度快于访问主存的速度,但通常比访问内部寄存器的速度还要慢一点。
  • 一个计算机还包含一个主存。所有的CPU都可以访问主存。主存通常比CPU中的缓存大得多。
  • 通常情况下,当一个CPU需要读取主存时,它会将主存的部分读到CPU缓存中。它甚至可能将缓存中的部分内容读到它的内部寄存器中,然后在寄存器中执行操作。当CPU需要将结果写回到主存中去时,它会将内部寄存器的值刷新到缓存中,然后在某个时间点将值刷新回主存。

Java内存模型和硬件内存架构之间的桥接

共享对象的可见性

如果两个或者更多的线程在没有正确的使用volatile声明或者同步的情况下共享一个对象,一个线程更新这个共享对象可能对其它线程来说是不接见的。

共享对象的可见性

可以使用volatile关键字解决这个问题

race condition

如果两个或者更多的线程共享一个对象,多个线程在这个共享对象上更新变量,就有可能发生race conditions。

更新变量发生 race condition

可以使用同步块解决这个问题

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容