返回

初识Java内存模型:共享变量、工作内存和主存

见解分享

初识Java内存模型

Java内存模型(Java Memory Model,简称JMM)定义了Java程序中变量的访问规则,保证了多线程程序的正确执行。JMM规定Java每个线程都有自己的工作内存(Working Memory),线程的工作内存中有共享变量的副本,共享变量则存放在主存(Main Memory)中。工作内存是线程私有的,而主存则是所有线程共享的。工作内存用于存放线程私有的数据。而Java内存模型中规定所有变量都存放在主存中,而共享变量同时也会在每个线程的工作内存中有一个副本。当一个线程修改共享变量时,它只修改自己工作内存中的副本,而不会修改主存中的变量。当其他线程需要访问共享变量时,它会从主存中读取共享变量的值。这就是Java内存模型中的可见性。

Java内存模型中的共享变量

共享变量是可以在多个线程中访问的变量。共享变量的可见性是Java内存模型中的一个重要概念。可见性是指一个线程对共享变量的修改能够被其他线程看到。JMM规定,当一个线程修改共享变量时,它必须将修改后的值写入主存。当其他线程读取共享变量时,它必须从主存中读取共享变量的值。这样才能保证共享变量的可见性。

Java内存模型中的工作内存

工作内存是线程私有的内存区域。工作内存中存储着该线程私有的数据,包括局部变量、方法参数和共享变量的副本。共享变量的副本是线程从主存中读取的。当一个线程修改共享变量时,它只修改自己工作内存中的副本,而不会修改主存中的变量。

Java内存模型中的主存

主存是所有线程共享的内存区域。主存中存储着共享变量。当一个线程修改共享变量时,它必须将修改后的值写入主存。当其他线程读取共享变量时,它必须从主存中读取共享变量的值。这样才能保证共享变量的可见性。

Java内存模型中的可见性规则

JMM规定了以下可见性规则:

  • 原子性规则: 原子性规则规定,对共享变量的读写操作是原子的。也就是说,一个线程对共享变量的修改是不可中断的。其他线程无法在修改操作完成之前看到共享变量的中间状态。
  • 有序性规则: 有序性规则规定,对共享变量的修改必须按照程序的顺序执行。也就是说,一个线程对共享变量的修改必须在其他线程看到修改后的值之前完成。
  • 一致性规则: 一致性规则规定,所有线程看到的共享变量的值必须是一致的。也就是说,一个线程对共享变量的修改必须被其他线程看到。

Java内存模型中的happen-before规则

happen-before规则是JMM中定义的一种关系。happen-before关系规定,如果一个操作happen-before另一个操作,那么第一个操作对共享变量的修改必须在第二个操作看到修改后的值之前完成。happen-before关系可以由以下三种方式建立:

  • 程序顺序规则: 程序顺序规则规定,在同一个线程中,一个操作happen-before紧跟其后的另一个操作。
  • 监视器锁规则: 监视器锁规则规定,如果一个线程获取了一个监视器的锁,那么该线程对该监视器保护的共享变量的修改happen-before释放该锁之前的所有操作。
  • volatile变量规则: volatile变量规则规定,如果一个线程将一个volatile变量的值写入主存,那么该线程对该volatile变量的修改happen-before其他线程看到修改后的值。

Java内存模型的实现

JMM的实现是通过编译器和运行时环境共同完成的。编译器负责将Java程序编译成字节码。字节码是Java虚拟机(JVM)可以执行的代码。JVM负责将字节码解释执行成机器指令。JVM在执行字节码时,会根据JMM的规定来保证多线程程序的正确执行。

Java内存模型的意义

JMM对于Java程序的正确执行非常重要。JMM保证了多线程程序的正确执行,避免了由于共享变量的可见性问题而导致的程序错误。JMM还为Java程序员提供了编写多线程程序的指导,帮助Java程序员编写出正确和高效的多线程程序。